删除传递给构造函数的对象指针导致错误

Deleting a object pointer passed to a constructor function causing an error

本文关键字:指针 错误 对象 构造函数 删除      更新时间:2023-10-16

我是C++的新手,所以我正试图借助维基百科上的例子来学习它。我玩了一些课,我有一个分段错误。

这是我的代码:

class SomeClass {};
class AnotherClass {
    SomeClass* sc
    public:
        AnotherClass(SomeClass* SC):( sc = SC; ){}
        //***********************************************************************
        ~AnotherClass(){ delete sc; } //here I'm getting rid of internal pointer
        //***********************************************************************
};
int main( int argc, char* argv[] ) {
    SomeClass* SC = new SomeClass();
    AnotherClass* AC = new AnotherClass(SC);
    delete AC;
    // *****************************************************
    delete SC; //i think that this line might cause an error
    //******************************************************
    return 0;
}

我想,我应该delete每个指针以获得堆内存空闲?!你能指出我的错误吗。

编辑:

这是我的真实代码:

#include <iostream>
#include <string>
using namespace std;
class Pizza {
    string dough;
    public:
        Pizza(string d):dough(d) {}
            void setDough( string value ) { dough = value; }
            string getDough() { return dough; }
};
class PizzaBuilder {
    Pizza* pizza;
    public:
        PizzaBuilder( Pizza* p ) { pizza = p; }
        ~PizzaBuilder() { delete pizza; cout << "PizzaBuilder Destructor." << endl;}
        PizzaBuilder* addExtra(string extra) { 
            string special = pizza->getDough() + " and extra " + extra;
            pizza->setDough(special);
            return this;
        }
        Pizza* getPizza() { return pizza; }
    };
int main(int argc, char* argv[]) {
    Pizza* p = new Pizza("My Special DOVE!");
    PizzaBuilder* pb = new PizzaBuilder(p);
    pb->addExtra("Mushrooms")->addExtra("Anchovies")->addExtra("Zefir")->addExtra("Chilli");
    cout << p->getDough() << endl;
    delete pb;
    delete p;
    return 0;
}

delete不会删除指针,正如您可能认为的那样。它删除指针指向的对象。因此,您要删除SC指向的对象两次:一次从main,另一次从删除时自动调用的AC指向的对象的析构函数。

多次删除一个对象是未定义的行为。

您需要决定谁拥有该对象。似乎您希望AnotherClass拥有SomeClass对象,如果您在析构函数中有delete,那么您不应该在main()中使用delete。双delete ing导致未定义的行为

避免这种情况的最好方法是使用std::shared_ptr,它管理对内存中同一对象的多个引用:

#include <memory>
class SomeClass {};
class AnotherClass {
    std::shared_ptr<SomeClass> sc
    public:
        AnotherClass(std::shared_ptr<SomeClass> SC): sc(SC){}
        //***********************************************************************
        ~AnotherClass(){ /* nothing */}
        //***********************************************************************
};
int main( int argc, char* argv[] ) {
    std::shared_ptr<SomeClass> SC(new SomeClass());
    std::shared_ptr<AnotherClass> AC(new AnotherClass(SC));

    return 0;
}

请注意,缺少对delete的调用。

首先,尽量不要处理原始指针。尤其是在开始C++的时候。请尝试使用值。

也就是说,当您将SC传递给构造函数时,对象存储指针,因此它有一个指向您在main中创建的同一对象的指针。在析构函数中,它删除该对象。然后main也尝试删除该对象。繁荣