释放内存两次

在C和C ++中,释放NULL指针将导致无法完成任务。

不过,我看到有人说如果你“两次释放内存”会导致内存损坏。

这是真的? 当你释放记忆两次时,引擎盖下发生了什么?

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. 

所以,在第一次free之后,你应该做p = NULL ,所以如果(任何机会),再次调用free(p) ,什么都不会发生。

这就是为什么两次释放内存是未定义的: 为什么在调用两次时自由崩溃

释放内存不会将指针设置为null。 指针仍然指向它曾经拥有的内存,但现在已将所有权转移回堆管理器。

堆管理器可能已经重新分配了陈旧指针所指向的内存。

再次释放它与说free(NULL) ,并将导致未定义的行为。

这是未定义的行为,可能导致堆损坏或其他严重后果。

free()表示空指针只是检查里面的指针值并返回。 该检查无助于两次释放一个块。

这是通常发生的事情。 堆实现获取地址并尝试通过修改自己的服务数据来“占用”该块的块。 根据堆实现,任何事情都可能发生。 也许它有效并且没有任何反应,也许服务数据已损坏,并且您有堆损坏。

所以不要这样做。 这是未定义的行为。 无论发生什么坏事。

是的,“未定义的行为”几乎总是导致崩溃。 (虽然“未定义的行为”按定义意味着“任何东西”,但各种类型的错误通常以非常可预测的方式运行。在free()的情况下,行为总是会出现段错误或相应的“内存保护错误”特征。)

如果你释放()一个指向除NULL之外的任何东西或者你malloc的东西,那就相同。

char x; char* p=&x; free(p); //崩溃

为了避免两次免费,我总是使用MACRO获取空闲内存:

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

这个宏设置p = NULL以避免悬空指针。

当您在指针上调用free时,您的指针将不会设置为NULL。 可用空间仅返回池中以便再次分配。 这是一个测试的例子:

 #include  #include  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; } 

这个程序为我输出:

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

你可以看到,free对指针没有任何作用,只是告诉系统内存可以重用。

free()释放ptr指向的内存空间,该内存空间必须由之前调用malloc(),calloc()或realloc()返回。 否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为。 如果ptr为NULL,则不执行任何操作。

所以,你得到了未定义的行为,任何事情都可能发生。

1)编译器不会处理动态内存。 有运行时库来处理这个问题。 例如。 :glibc提供了像malloc和free这样的API,它们在内部进行系统调用(sys_brk)来处理堆区域。

2)释放相同的内存两次指的是这样的条件:假设你有char * cptr;

您可以使用以下命令分配内存:cptr =(char *)malloc(SIZE);

现在,当你不再需要这个内存时,你可以使用它释放它:free(cptr);

现在发生的事情是cptr指向的内存是免费使用的。

假设在程序的稍后时间点再次调用free(cptr),那么这不是一个有效的条件。 这种两次释放相同内存的场景被称为“释放两次内存”问题

不止一次释放内存会产生不良后果。 您可以运行此代码以查看计算机可能发生的情况。

 #include  /* printf, scanf, NULL */ #include  /* malloc, free, rand */ int main () { int i,n; char * buffer; printf ("How long do you want the string? "); scanf ("%d", &i); buffer = (char*) malloc (i+1); if (buffer==NULL) exit (1); for (n=0; n 

许多标准库(如CSparse)使用包装函数来处理内存问题。 我复制了这里的function:

  /* wrapper for free */ void *cs_free (void *p) { if (p) free (p) ; /* free p if it is not already NULL */ return (NULL) ; /* return NULL to simplify the use of } 

此function可以处理内存问题。 请注意,在某些情况下,您必须注意malloc返回NULL的条件