释放内存两次

时间:2010-03-18 10:01:33

标签: c++ c memory-management memory-leaks free

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

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

这是真的吗?当你两次释放记忆时,幕后发生了什么?

9 个答案:

答案 0 :(得分:23)

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),就不会发生任何事情。

这就是为什么两次释放内存是未定义的:Why free crashes when called twice

答案 1 :(得分:19)

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

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

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

答案 2 :(得分:9)

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

free()对于空指针只是检查内部的指针值并返回。该检查无助于两次释放一个块。

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

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

答案 3 :(得分:4)

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

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

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

答案 4 :(得分:4)

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

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

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

答案 5 :(得分:3)

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

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

这个程序为我输出:

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

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

答案 6 :(得分:2)

  

free()释放指向的内存空间   通过ptr,一定是   之前的电话回复   malloc(),calloc()或realloc()。   否则,或者如果已经免费(ptr)   以前被称为未定义   行为发生。如果          ptr为NULL,不执行任何操作。

因此,您会得到未定义的行为,并且可能发生任何事情。

答案 7 :(得分:1)

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

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

您使用以下方式分配内存: cptr =(char *)malloc(SIZE);

现在,当您不再需要此内存时,可以使用以下内容释放它: 自由(CPTR);

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

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

答案 8 :(得分:0)

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

#include <stdio.h>      /* printf, scanf, NULL */
#include <stdlib.h>     /* 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<i; n++)
          buffer[n]=rand()%26+'a';
  buffer[i]='\0';

  printf ("Random string: %s\n",buffer);
  free (buffer);
  free (buffer);

  return 0;
}

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

 /* 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    

    }

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

相关问题