删除整数指针时析构函数末尾的分段错误

时间:2014-11-14 11:15:28

标签: c++ destructor

我想了解下面的程序。执行时遇到错误,如下所示。

#include<iostream>
using namespace std;
class Base
{
public:
    int *a;
    int a1;
    int b;


    Base(){
        cout<<"Inside Constructor"<<endl;
        a1 = 10;
        a = &a1;
        cout<<"   "<<a<<endl;
        b = 20;
    }

    Base(const Base &rhs)
    {
        cout<<"Inside Copy Constructor"<<endl;
        a = new int;
        *a = *(rhs.a);
        b = rhs.b;
    }

    ~Base(void)
    {
    cout<<"Inside destructor"<<endl;
    delete a;
    }
};


int main()
{
Base obj;
Base obj2(obj);
cout<<"obj a "<<*(obj.a)<<" b "<<obj.b<<endl;
cout<<"obj2 a "<<*(obj2.a)<<" b "<<obj2.b<<endl;
obj.a1 = 30;
obj.b = 40;
cout<<"obj a "<<*(obj.a)<<" b "<<obj.b<<endl;
cout<<"obj2 a "<<*(obj2.a)<<" b "<<obj2.b<<endl;
return 0;
}

执行此代码时,我得到以下输出

Inside Constructor
Inside Copy Constructor
obj a 10 b 20
obj2 a 10 b 20
obj a 30 b 40
obj2 a 10 b 20
Inside destructor
Inside destructor
Segmentation fault

[编辑] 我一直在寻找一种方法来破坏我在拷贝构造函数中创建的堆内存。那么这里可以做些什么呢?请建议

[编辑]

4 个答案:

答案 0 :(得分:1)

delete应该在使用new only的堆分配的内存上使用。

a1 = 10;
a = &a1;

在你的情况下&#34; a&#34;正在堆栈中保存内存的地址。所以,你不应该在那个记忆中调用删除。

答案 1 :(得分:0)

您必须删除使用new(动态分配)获取的内存,而不是删除自动存储变量。

答案 2 :(得分:0)

在复制构造函数中,您使用 new operator 为指针 a 分配内存,因此您可以将其删除。但是因为您没有使用 new运算符在默认构造函数中,您可以删除指针 a 。 您必须使用delete opearator来释放堆中不在堆栈中的变量的内存。

当您使用 new operator 时,变量在中创建,其中在堆栈内存中创建局部变量,但不能使用删除运算符

删除

答案 3 :(得分:0)

问题不在于复制构造函数,问题是你不能一直使用new(如果你使用移动那么也许你会有一个观点)。你有一些选择。我想要有用,而不是详尽无遗,也许我错过了其他好的设计理念。

始终(始终如一)使用new

您可以在所有构造函数中添加一个new,因此析构函数始终可以调用delete。即使你不需要它。这可能是一个丑陋的黑客,但是是一致的。

永远不要使用new

如果您从未使用过new,则也不要使用delete,编译器会确保一致性并确保您不会陷入困境。通常,您可以依赖构造函数上的编译器默认行为。

使用智能指针

如果不是手动调用delete而是将变量保存在unique_ptr内,那么编译器会自动在析构函数中释放它。智能指针非常智能,可以知道它是否已初始化。

请注意,使用智能指针意味着您永远不应该调用delete,因为如果您这样做而没有警告智能指针,您将遇到同样的问题。如果您不熟悉它们并且使用的是C ++ 11,那么学习它是一件好事:)

跟踪指针的状态

我不会保证这一点。它似乎非常C而非C++。但是,您始终可以跟踪bool值并在销毁时检查它。这就像使用智能指针一样,但内部实现。我认为这是一个糟糕的设计理念,虽然在某些情况下具有教育意义。