当两个类共享同一个堆对象时,如何避免两次删除指针?

时间:2015-09-18 17:20:16

标签: c++ pointers destruction

当两个类共享同一个堆对象时,如何避免两次删除指针?我遇到过这种问题:两个大类对象共享一个大对象。在初始函数中初始化。因为它很大,所以我不想复制它们。我在堆中分配它们并保存指针:

class A {
   public:
     A(C* in_p) : p(in_p){}
     ~A() {delete p;}
   private:
   C* p;
}
class B {
   public:
      B(C* in_p) : p(in_p){}
      ~B(){delete p;}
   private:
   C* p;
}
class C {
    public:
    ~C() {...}
}
void initial(A* pa, B* pb) {
     C* a = new C;
     C* b = a;
     pa = new A(a);
     pb = new B(b);
     ... some other initialization codes
}
int main() {
    A* pa = nullptr;;
    B* pb = nullptr;
    initial(pa, pb);
    ........ some processing codes
    //clear up
    delete pa;
    delete pb;
}

但是当我清理它们时,问题出在A的破坏之后,C类的实例不在堆中。然后B的析构函数删除相同的堆区域,并调用C的析构函数,它崩溃,因为那里没有C的指针,调用C->destructor将崩溃。在C被删除后,B不知道A已经不存在,而当B破坏自己的(C*)p时,A的成员(C*)p不会改变{1}}。

我既不能通过引用传递C* p,也不能将C**传递给A的{​​{1}}和p B。在p完成后,本地堆栈变量initial()将不再存在。因此,在C*(a) C*(b)之后,initial()的{​​{1}}和A的{​​{1}}将存储未知的内存地址,并且在使用时会崩溃。

那么在智能指针出现之前,你在C ++用户自我管理的传统垃圾收集中处理这种情况是什么?

1 个答案:

答案 0 :(得分:2)

使用std::shared_ptr。如果您没有,请使用boost::shared_ptr。如果你不能使用它,请根据boost的设计编写自己的。除非您的C ++编译器已有几十年的历史,否则我认为您无法使用这三个选项之一。