运行某些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;
}
有人可以解释为什么第一个导致段错误而第二个不导致错误?我知道指针无效,因为它已被赋值给数字变量的地址。
答案 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函数中的变量也会自动释放。 所以你不能对程序说取消分配堆栈中的变量。 在你的例子中,数字在堆栈上,指针指向堆栈中的数字,如果你删除它,你试图删除堆栈中的变量,这是不允许的,因为它不是动态内存。