Freeing memory twice

2019-03-10 21:03发布

In C and C++, Freeing a NULL pointer will result in nothing done.

Still, I see people saying that memory corruption can occur if you "free memory twice".

Is this true? What is going on under the hood when you free memory twice?

9条回答
迷人小祖宗
2楼-- · 2019-03-10 21:14
int *p = malloc(sizeof(int));
//value of p is now lets say 0x12345678

*p = 2;
free(p); //memory pointer is freed, but still value of p is 0x12345678
         //now, if you free again, you get a crash or undefined behavior.

So, after free ing the first time, you should do p = NULL , so if (by any chance), free(p) is called again, nothing will happen.

Here is why freeing memory twice is undefined: Why free crashes when called twice

查看更多
SAY GOODBYE
3楼-- · 2019-03-10 21:16

When you call free on a pointer, your pointer will not get set to NULL. The free space is only given back to a pool to be available for allocation again. Here an example to test:

#include <stdio.h>
#include <stdlib.h>

int main(){
    int* ptr = (int*)malloc(sizeof(int));
    printf("Address before free: %p\n", ptr);
    free(ptr);
    printf("Address after free: %p\n", ptr);
    return 0;
}

This program outputs for me:

Address before free: 0x950a008
Address after free: 0x950a008

and you can see, that free did nothing to the pointer, but only told the system that the memory is available for reuse.

查看更多
我命由我不由天
4楼-- · 2019-03-10 21:20

Freeing memory does not set the pointer to null. The pointer remains pointing to the memory it used to own, but which has now had ownership transferred back to the heap manager.

The heap manager may have since reallocated the memory your stale pointer is pointing to.

Freeing it again is not the same as saying free(NULL), and will result in undefined behavior.

查看更多
虎瘦雄心在
5楼-- · 2019-03-10 21:24

To avoid free twice i alway using MACRO for free memory:

#ifdef FREEIF
# undef FREEIF
#endif
#define FREEIF( _p )  \
if( _p )              \
{                     \
        free( _p );   \
        _p = NULL;    \
}

this macro set p = NULL to avoid dangling pointer.

查看更多
看我几分像从前
6楼-- · 2019-03-10 21:28

Yes, "undefined behavior" which almost always results in a crash. (while "undefined behavior" by definition means "anything", various types of errors often behave in quite predictable ways. In case of free(), the behavior is invariably segfault or respective "memory protection error" characteristic to the OS.)

Same if you free() a pointer to anything else than NULL or something you malloc'd.

char x; char* p=&x; free(p); // crash.

查看更多
虎瘦雄心在
7楼-- · 2019-03-10 21:31

This is undefined behavior, that can result in heap corruption or other severe consequences.

free() for a null pointer simply checks the pointer value inside and returns. That check will not help against freeing a block twice.

Here's what happens usually. The heap implementation gets the address and tries to "take ownership" of the block at that address by modifying its own service data. Depending on the heap implementation anything can happen. Maybe it works and nothing happens, maybe the service data is corrupted and you've got heap corruption.

So don't do it. It's undefined behavior. Whatever bad things can happen.

查看更多
登录 后发表回答