ご存知かもしれませんが、malloc
OSを呼び出すたびにメモリが確保され、サイズと属性が記憶されます。したがって、を呼び出すとfree
、配列またはポインタの両方をクリアできます。
例:
char* array = malloc(16 * sizeof(char));
char* single = malloc(sizeof(char));
free(array);
free(single);
ご覧のとおり、常に1free
対1で取得できますmalloc
。これは、OSが割り当てたバイト数を認識しているため、OSがどのタイプであり、作成されたインスタンスの数を気にしないためです。(注:アプリケーションは実行するデストラクタを知る必要があるため、C ++delete
とでは違いがあるのはこのためです。クリーンアップの制御はOSだけに任されていません...)delete[]
ここから、単一のを使用して構造体を1つのブロックとして割り当てた場合、単一の呼び出しmalloc
を使用して構造体を解放できると想定できます。free
この例は、リークなしで機能します。
#include <stdlib.h>
typedef struct Array_t
{
int Length;
double Data[];
} Array;
Array* create_array(int length)
{
Array* array = malloc(sizeof(Array) + length * sizeof(double));
if (array != NULL)
array->Length = length;
return array;
}
void delete_array(Array* array)
{
free(array);
}
int main()
{
Array* array = create_array(100);
if (array == NULL)
return EXIT_FAILURE;
for (int i = 0; i < array->Length; ++i)
{
array->Data[i] = 1.7 * (i + 3);
}
delete_array(array);
return EXIT_SUCCESS;
}
もちろん、JohnFindlayの例のようなもっと複雑なものに出くわした場合
struct SomeStruct
{
int Size;
int* ArrayOfPointers[];
}
この構造体は1つで作成できますmalloc
。例:
// *s* contains an array of 14 int pointers (int*)
struct SomeStruct* s = malloc(sizeof(SomeStruct) + 14 * sizeof(int*));
s->Size = 14;
コアの問題は、それint* ArrayOfPointers
がポインタの配列であるということです。したがって、適切に初期化するには、次のことも行う必要があります。
// each of the *s*'s int pointers is actually a decayed array of 25 ints
for (int i = 0; i < s->Size; ++i)
s->ArrayOfPointers[i] = malloc(25 * sizeof(int));
そして解放するとき:
for (int i = 0; i < s->Size; ++i)
free(s->ArrayOfPointers[i]);
free(s);
ただし、重要なのは、FAMを使用した構造が1回のfree
呼び出しで解放されるということです。ループは、割り当てられたポインタデータを解放します。これは、動的に割り当てられた2D配列を解放することと同じです。