【问题标题】:How do I avoid deleting a pointer twice when two classes share the same heap object?当两个类共享同一个堆对象时,如何避免两次删除指针?
【发布时间】:2015-09-18 17:20:16
【问题描述】:

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

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会崩溃。 B不知道CA被删除后已经不存在,B的成员(C*)pA销毁自己的(C*)p时不会改变。

我既不能通过引用传递C* p,也不能通过C**链接ApBp,因为在initial()完成后,本地堆栈变量@987654342 @ 将不再存在。所以initial()A(C**)pB(C**)p会存储未知的内存地址,使用时会崩溃。

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

【问题讨论】:

  • initial 不会通过引用(或**)获取papb,因此该函数中对papb 的任何分配都不会反映在@987654354 之外@.
  • 欢迎来到 SO!你能提供一个minimal, complete, and reproducible example吗?您没有展示任何共享...papb 拥有不同的 C 对象。
  • 那么在智能指针出现之前,C++ 用户自行管理的传统垃圾回收中的这种情况如何处理? 程序员创建了自己的智能指针类。
  • 你觉得智能指针是怎么写的?带着仙尘?
  • 如果你有nullptr,那么为什么没有std::shared_ptr

标签: c++ pointers destruction


【解决方案1】:

使用std::shared_ptr。如果没有,请使用boost::shared_ptr。如果不能使用,就根据boost的设计自己写。除非您的 C++ 编译器已有数十年历史,否则我看不出有任何理由您不能使用这三个选项之一。

【讨论】:

    猜你喜欢
    • 2021-12-28
    • 2012-01-06
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    相关资源
    最近更新 更多