删除指针时的Segfault

时间:2012-02-10 22:34:45

标签: c++ pointers segmentation-fault

运行某些C ++代码时,我遇到了段错误。我已将问题隔离到程序中删除指针的行。这是一个产生相同错误的简单示例:

int main()
{
  int* pointer=0;
  int number = 3;

  pointer = &number;
  delete pointer;//This line causes a segmentation fault
  pointer=0;

  return 0;
}

稍作修改会生成符合预期的代码:

int main()
{
  int* pointer=new int(3);

  delete pointer;//This line now works
  pointer=0;

  return 0;
}

有人可以解释为什么第一个导致段错误而第二个不导致错误?我知道指针无效,因为它已被赋值给数字变量的地址。

5 个答案:

答案 0 :(得分:16)

您应该只delete已使用new分配的内存。在堆栈上声明的自动变量不需要是delete d。通常,始终匹配您的内存分配和释放类型:

  • 应使用new
  • 取消分配使用delete分配的内存
  • 应使用new []
  • 取消分配使用delete []分配的内存
  • 应使用malloc()
  • 取消分配使用free()分配的内存

段错误是因为delete运算符将尝试将该内存放回堆中,并且依赖于内存的某些属性,这些属性对于堆栈上的自动内存不适用来源于堆。

答案 1 :(得分:3)

您无法对delete未获得的任何内容使用new。尝试这样做会导致未定义的行为。你的程序崩溃了,但任何都可能发生。

答案 2 :(得分:2)

对指针调用delete,释放指针指向的动态分配的内存。

在第一个程序中,指针指向静态分配的内存位置。变量号是一个“自动”变量,这意味着它的内存是自动管理的。

另一方面,在第二个程序中,指针指向堆段中分配的内存位置,需要通过调用delete手动取消分配。

您可能会发现此link有用。

答案 3 :(得分:0)

delete指针未分配new时,您将在内存管理系统和堆栈之间产生冲突。每个操作都会像它仍然拥有内存的唯一所有权一样运行,并且当它们覆盖彼此的值时会导致崩溃。

答案 4 :(得分:0)

使用new分配变量时:

int *a=new int(4);

此变量放在堆上,其中包含dnamicly分配的所有内存。 相反,如果你声明一个变量:

int a=4;

a在堆栈中分配,其中有静态内存。 动态内存可以通过用户删除来释放,但静态内存不能。 当yuo exit froma功能时,静态存储器自动解除分配:

void function()
{
    int a;
}

当函数结束时,a会自动释放(除了使用关键字“static”声明的变量)。 此外,main函数中的变量也会自动释放。 所以你不能对程序说取消分配堆栈中的变量。 在你的例子中,数字在堆栈上,指针指向堆栈中的数字,如果你删除它,你试图删除堆栈中的变量,这是不允许的,因为它不是动态内存。