问题描述:

I'm trying to free all my memory, and I'm not sure if I'm doing it properly for a struct*. A snippet of my code:

struct words { char word[40]; };

int main() {

struct words* aList = malloc(2*sizeof(struct words));

// A text file is opened and each word is stored in a struct. I use an int variable to count how many times I've stored a word.//

if(n >= 2*sizeof(struct words) {

n = n*2;

aList = realloc(n*sizeof(struct words));

//Once my program is done, at the end of my main.//

free(aList);

From my understanding of C (I've only been using it for about 2 months), I've created an array of struct pointers at the start. Then I'm dynamically increasing the size of the array with realloc. When I free aList from memory, does it only free the addresses stored in aList?

网友答案:
void* ptr = malloc(512);

This provides you with a block of memory which contains 512 bytes of data. That doesn't mean the block is 512 bytes big, it means that it contains 512 bytes or more.

Typically, each block has a small prefix which is used by the allocator.

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);
}

Then understand that realloc is implemented by allocating a new block for the new size, copying the data over and releasing the old allocation.

So you can't release sub-allocations of an allocation:

int* mem = malloc(4 * sizeof(int));
free(int + 3); // invalid

HOWEVER.

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.

You are responsible for free()ing each of the allocations here.

// mem[3] was NOT an malloc
free(mem[2]);
// mem[1] was NOT an malloc
free(mem[0]);
free(mem);

but this is a matter of matching allocations to frees.

相关阅读:
Top