void* ptr = malloc(512);
これにより、512 バイトのデータを含むメモリ ブロックが提供されます。これは、ブロックの大きさが512 バイトであることを意味するのではなく、512 バイト以上が含まれていることを意味します。
通常、各ブロックには、アロケーターによって使用される小さなプレフィックスがあります。
struct MemoryBlock {
size_t howBigWasIt;
char data[0]; // no actual size, just gives us a way to find the position after the size.
};
void* alloc(size_t size) {
MemoryPool* pool = getMemoryPool(size);
MemoryBlock* block = getFirstPoolEntry(pool);
block->howBigWasIt = size;
return &block->data[0];
}
static MemoryBlock blockForMeasuringOffset;
void free(void* allocation) {
MemoryBlock* block = (MemoryBlock*)((char*)allocation) - sizeof(MemoryBlock));
MemoryPool* pool = getMemoryPool(block->howBigWasIt);
pushBlockOntoPool(pool, block);
}
次に、新しいサイズに新しいブロックを割り当て、データをコピーして古い割り当てを解放することで、realloc が実装されることを理解してください。
したがって、割り当てのサブ割り当てを解放することはできません。
int* mem = malloc(4 * sizeof(int));
free(int + 3); // invalid
でも。
int i = 0;
int** mem = malloc(4 * sizeof(int*));
mem[0] = malloc(64);
mem[1] = alloca(22); // NOTE: alloca - this is on the stack.
mem[2] = malloc(32);
mem[3] = &i; // NOTE: pointer to a non-allocated variable.
ここで各割り当てを free() するのはあなたの責任です。
// mem[3] was NOT an malloc
free(mem[2]);
// mem[1] was NOT an malloc
free(mem[0]);
free(mem);
しかし、これは解放への割り当てを一致させる問題です。