简体   繁体   中英

free allocated memory by posix_memalign by freeing a pointer that points to this memory

When allocating memory using posix_memalign does calling free on the pointer that points to the pointer of the allocated memory free all the allocated memory? In this example, when I free pointer_to_data and then look at the original pointer I still see the same data in all allocations but not the last ones!

unsigned char *data = nullptr;
unsigned int  data_size = 512;

posix_memalign((void **) &data, 16, data_size);
memset(data, 0, data_size);

for (int i = 0; i < data_size; i++){
    data[i] = 0xff;
}

unsigned char *pointer_to_data = data;
free(pointer_to_data);


for (int i = 0; i < data_size; i++){
    printf( " %x ",data[i]);
}

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 10 0

unsigned char *pointer_to_data = data;

This is not a pointer to the pointer, it's a copy of the pointer, also called an alias . It points to the same address as data itself does. Calling free(pointer_to_data) has precisely the same effect as calling free(data) .

Freeing a block of memory is not guaranteed to make its previous contents inaccessible. Rather, trying to access that region of memory is undefined behavior . You might see the data that was previously there, if the allocator has chosen to reserve that region of memory for future allocations. You might see metadata placed there by the allocator itself. You might see data placed there by a different part of the program, if the space has been allocated again. You might get a segmentation fault, if the memory has been returned to the OS and unmapped. Literally anything could legally happen, and most of the possibilities will be ones you won't like. So it is your responsibility to ensure that your program just doesn't do that, and to not write code like what you have written.

To repeat, the distinction between data and pointer_to_data has nothing to do with this. You'd have seen exactly the same (undefined) behavior if you had done free(data) instead.

(If the data stored in that block was sensitive, eg encryption keys, then you need to ensure that you overwrite it before you free() it; you can't rely on free() to do that for you. This is a more difficult thing to do properly than it would appear, since other copies of the data may exist elsewhere and you have to be sure to overwrite them all. If this is your situation, you should probably get expert advice.)

Note that everything mentioned above is just the same for malloc() as for posix_memalign() .

If you really wanted a pointer to the pointer, you would write

unsigned char **actually_a_pointer_to_data;
actually_a_pointer_to_data = &data;

In that case free(actually_a_pointer_to_data) would itself be undefined behavior, because actually_a_pointer_to_data does not point to the same address as data does, and in particular is not the address that was returned by posix_memalign which is the only one you may legally free() . However free(*actually_a_pointer_to_data) would be equivalent to free(data) .

When allocating memory using posix_memalign does calling free on the pointer that points to the pointer of the allocated memory free all the allocated memory?

It's unclear whether "the pointer that points to the pointer of the allocated memory" belies a misunderstanding or whether it's just poor wording. I don't see a way to interpret it that matches the example presented.

To free allocated memory, including memory allocated via posix_memalign , one must pass to free() a pointer to the base address provided by the allocation function. posix_memalign() is unusual among the standard allocation functions in that it writes that pointer via an out parameter instead of returning it, so here ...

 unsigned char *data = nullptr; unsigned int data_size = 512; posix_memalign((void **) &data, 16, data_size);

... the base address in question is recorded in variable data , whose own address is passed as the first argument to posix_memalign to enable that function to modify its value. The pointer value that posix_memalign writes there is the one that must subsequently be passed to free , but all C function arguments are passed by value, so only the value passed can make a difference, not the expression that produced that value.

Thus, if you do this ...

 unsigned char *pointer_to_data = data;

... then you have just copied the (pointer) value of data to variable pointer_to_data , so that it is true that data == pointer_to_data . You may then free the allocated block by passing the (same) value obtained from either variable to free() . This is a valid way to free the allocated space:

 free(pointer_to_data);

You go on to remark that

In this example, when I free pointer_to_data and then look at the original pointer I still see the same data in all allocations but not the last ones!

Freeing the allocated space makes it available for reallocation, and terminates the lifetime of the allocated object . Attempting to access the value of an object whose lifetime has ended produces undefined behavior. If you suppose (unsafely) that you can continue to use a pointer to the freed space to examine the no-longer-allocated memory then there is no reason to expect the memory to have changed, but also no reason to expect that it has not.

In particular, memory allocators do not typically go out of their way to overwrite the contents of freed memory blocks, but it may in some cases serve a purpose to modify some or all of that memory, or some or all of it may be reallocated and possibly overwritten soon after it becomes available, such as in the calls to printf in your example code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM