删除指针时出现分段错误

Segfault when deleting pointer

本文关键字:分段 错误 指针 删除      更新时间:2023-10-16

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

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

有人能解释为什么第一个会导致segfault,而第二个不会吗?我知道指针不是无效的,因为它被分配给了数字变量的地址。

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

  • 分配给new的内存应与delete解除分配
  • 分配给new []的内存应与delete []解除分配
  • 分配给malloc()的内存应与free()解除分配

segfault是因为delete运算符将尝试将该内存放回堆中,并且这依赖于内存的某些属性,而这些属性对于不是源自堆的堆栈上的自动内存不成立。

您不能将delete用于new没有得到的任何东西。试图这样做会导致未定义的行为。你的程序崩溃了,但任何的事情都可能发生。

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

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

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

你可能会发现这个链接很有用。

当您delete是一个没有用new分配的指针时,您在内存管理系统和堆栈之间创建了冲突。每一个都将像仍然拥有内存的唯一所有权一样运行,当它们覆盖彼此的值时,可能会导致崩溃。

当您用new分配变量时:

int *a=new int(4);

这个变量被放在堆中,堆中包含dnamicly分配的所有内存。如果您声明一个变量:

int a=4;

a在堆栈中分配,堆栈中有静态内存。动态内存可以通过从用户删除来解除分配,但静态内存不能。当你退出一个函数时,静态内存会自动释放:

void function()
{
    int a;
}

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