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);
但这是将分配与释放匹配的问题。