2012-02-10 112 views
2

运行某些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; 
} 

有人可以解释为什么首先使段错误和第二个不?我知道指针不是无效的,因为它已被分配给数字变量的地址。

+4

第一个没有分配'new',因此调用'delete'并不是正确的做法。 – ildjarn 2012-02-10 22:36:01

回答

14

您应该只有delete内存已被分配new。在堆栈中声明的自动变量不需要为delete d。作为一项规则,总是与你的内存分配和释放类型:与new分配

  • 内存应该delete被释放。
  • 分配给new []的内存应该用delete []解除分配。
  • 分配到malloc()的内存应该用free()解除分配。

的段错误是因为delete运营商将试图把内存放回堆,并且依赖于那些不为没有来源的堆栈内存自动保持真实记忆的某些属性从堆。

3

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

0

如果您指针未分配new,则会在内存管理系统和堆栈之间产生冲突。每个操作都会像处理内存的唯一所有权一样操作,并且当它们覆盖对方的值时可能导致崩溃。

0

当您分配了新一variabile的:

int *a=new int(4); 

这个变量被放在堆,它包含了所有的内存分配dnamicly。 相反,如果你声明一个变量:

int a=4; 

一个在栈中,那里是静态存储器分配。 动态内存可以通过从用户删除来释放,但静态内存不能。

void function() 
{ 
    int a; 
} 

当函数结束时被自动释放(除了与关键字“静态”声明的变量):当宥出口弗罗马功能 静态存储器程序自动释放。 主函数中的变量也会自动解除分配。 所以你不能说程序在堆栈中释放一个变量。 在您的示例中,数字在堆栈中,指针指向堆栈中的数字,如果您删除它,则尝试删除堆栈中的变量,这是不允许的,因为它不是动态内存。

2

调用指针上的删除,释放指针指向的动态分配的内存。

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

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

您可能会感兴趣这个link有用。