在删除两次指针时堆积损坏

发布于 2025-02-13 14:52:56 字数 534 浏览 3 评论 0原文

两个类A和B类共享指向第三类C的指针,当A或B删除A或B时,它们也称为Delete C。

当仅删除A或B中的任何一个时,就不会观察到问题。 在这种情况下,一个例外是被抛弃了。我专门尝试将C类指针设置为NULL,并进行了无效检查以避免这种特定情况,但是此无效检查不起作用。

在这种情况下,我已经阅读了该共享指针,但我不确定如何正确实施。看来需要更改整个代码库以包含各处的共享_ptr,因为所有C类对象都将更新为shared_ptr。有什么方法可以使用shared_ptr仅在不更改所有代码的情况下存储此指针?

编辑: 我专门删除了C的分配运算符和C的复制构造函数,以避免情况由于复制而具有不同的指针。可以做其他任何事情以防止约翰指向答案的复制

class A{
  C* c;
}
~A(){
  if(C != NULL){
  delete C;
  C = NULL;
 }
}

class B{
 C* c;
}

~B(){
  if(C != NULL){
  delete C;
  C = NULL;
 }
}

Two classes A and B share pointer to a third class C and when either A or B are deleted they call delete C as well.

Issue is not observed when only either of A or B is deleted.
An exception is getting thrown in this scenario. I have specifically tried to set the class C pointer to NULL and have put in a NULL check to avoid this specific scenario but this null check is somehow not working.

I have read around that shared pointer should be used in this case but I am not sure how to implement it properly. It looks like whole code base needs to be changed to include shared_ptr everywhere as all class C objects would be updated to shared_ptr. Is there a way I can use shared_ptr just to store this pointer without changing all the code?

Edit:
I have specifically deleted assignment operator and copy constructor of C to avoid situation both have different pointers due to copying. Can anything else can be done to prevent copying as pointed in answer by john

class A{
  C* c;
}
~A(){
  if(C != NULL){
  delete C;
  C = NULL;
 }
}

class B{
 C* c;
}

~B(){
  if(C != NULL){
  delete C;
  C = NULL;
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮光之海 2025-02-20 14:52:56

ab具有指向c的单独的副本。因此,将该指针的一个类副本设置为null对另一个指针没有影响,您仍然会获得双重删除。

您基本上有四个选项

  1. 决定一个类“拥有”指针,该类将删除它,而另一个则不会。这里的危险是,如果拥有类删除指针,然后非持有类使用指针,那么您将获得另一种错误。

  2. 使用指针的共享所有权,因此只有在使用其最后的对象被破坏时,它才会被删除。这样做的简单方法是使用std :: shared_ptr

      #include< memory>
    
    A类{
        std :: shared_ptr< c> c;
    };
    
    B级{
        std :: shared_ptr< c> c;
    };
     
  1. 在将指针复制到第二类之前,请克隆。大致喜欢

    的东西

      ac = new C();
     bc = new C(*ac);
     

两个类都获得c对象的单独(但相等)的副本。但这更改了程序的语义,也许您实际上想要ab共享相同的c对象。

  1. 此选项(理查德·克里特(Richard Critten)建议)具有类具有std :: shared_ptr和类 b 具有std :: feek_ptr。这意味着a拥有c对象,当最后一个a对象被销毁时,c对象将也被摧毁。剩下的任何b对象都不会阻止c对象的破坏,但是,b对象可以检查c 对象已被破坏。在代码中,它看起来像这样

      #include< memory>
    
    A类
    {
        std :: shared_ptr< c> c;
    };
    
    b
    {
        std :: feek_ptr< c> c;
    };
    
    c
    {
         C(任何);
    };
    
    a a;
    b b;
    //创建共享指针
    ac = std :: make_shared< c>(whyther);
    //创建一个较弱的指针,涉及同一C对象
    bc = ac;
    
    //从B中的弱指针创建共享指针
    auto c = bclock();
    //检查指针是否有效
    如果(c)
    {
         //与C一起做某事
         c-> somings();
    }
    别的
    {
         // c对象已被破坏
    }
     

A and B have separate copies of the pointer to C. So setting one classes copy of that pointer to NULL has no effect on the other pointer and you still get a double delete.

You have basically four options

  1. Decide that one class 'owns' the pointer, that class will delete it and the other will not. The danger here is that if the owning class deletes the pointer and then the non-owning class uses the pointer then you are going to get a different kind of error.

  2. Use shared ownership of the pointer, so that it only gets deleted when the last object using it gets destroyed. The easy way to do that is to use std::shared_ptr

    #include <memory>
    
    class A {
        std::shared_ptr<C> c;
    };
    
    class B {
        std::shared_ptr<C> c;
    };
    
  1. Clone the pointer before copying it to the second class. Something roughly like

     a.c = new C();
     b.c = new C(*a.c);
    

this way both classes get separate (but equal) copies of the C object. But this changes the semantics of your program, maybe you actually want A and B to share the same C object.

  1. This option (suggested by Richard Critten) has class A having a std::shared_ptr and class B having a std::weak_ptr. This means that A owns the C object, and when the last A object has been destroyed the C object will also be destroyed. Any remaining B objects do not prevent the destruction of the C object but, the B object can check whether the C object has been destroyed. In code it looks something like this

    #include <memory>
    
    class A
    {
        std::shared_ptr<C> c;
    };
    
    class B
    {
        std::weak_ptr<C> c;
    };
    
    class C
    {
         C(whatever);
    };
    
    A a;
    B b;
    // create a shared pointer
    a.c = std::make_shared<C>(whatever);
    // create a weak pointer referring to the same C object
    b.c = a.c;
    
    // create a shared pointer from the weak pointer in b
    auto c = b.c.lock();
    // check if the pointer is valid
    if (c)
    {
         // do something with c
         c->something();
    }
    else
    {
         // c object has been destroyed
    }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文