【问题标题】:Assigning a dereferenced shared_ptr分配一个取消引用的 shared_ptr
【发布时间】:2013-09-17 01:38:27
【问题描述】:

考虑以下类:

struct MyClass {
    int mId;
    MyClass(int id): mId(id) {}
   ~MyClass() { std::cout << "deleting: " << mId << std::endl; }
};

及用法:

std::shared_ptr<MyClass> p(new MyClass(0));
MyClass& m = *p;
m = MyClass(2);

结果是:

deleting: 2
deleting: 2

请帮助我理解:

  1. 为什么有两个 MyClass(2) 对象(在析构函数日志中做出的假设)
  2. 这是内存泄漏吗? MyClass(0) 不应该泄漏吗?

谢谢。

【问题讨论】:

  • 把 prints 放到“Constructor/Copy Constructor/Assignment/Destructor”中,你可以更清楚地看到创建和销毁。
  • 呃.. @LokiAstari 你让我觉得很尴尬 :)

标签: c++ memory-leaks shared-ptr dereference


【解决方案1】:

这样做是为了更清楚地了解创造破坏:

struct MyClass {
    int mId;
    MyClass(int id): mId(id) {std::cout << "Creating: " << this << "(" << mId << ")\n";}
   ~MyClass()                {std::cout << "Deleting: " << this << "(" << mId << ")\n";}
    MyClass(MyClass const& c)
                             {std::cout << "Copy:     " << this << "(" << mId << ")\n"
                                           "    From: " << &c   << "(" << c.mId << ")\n";
                              mId=c.mId;
                             }
    MyClass& operator=(MyClass const& c)
                             {std::cout << "Assign:   " << this << "(" << mId << ")\n"
                                           "    From: " << &c   << "(" << c.mId << ")\n";
                              mId=c.mId;
                             }
};

当我跑步时,我得到:

Creating: 0x7fc741c000e0(0)
Creating: 0x7fff50ac38c0(2)
Assign:   0x7fc741c000e0(0)
    From: 0x7fff50ac38c0(2)
Deleting: 0x7fff50ac38c0(2)
Deleting: 0x7fc741c000e0(2)

【讨论】:

    【解决方案2】:

    没有内存泄漏。这段代码:

    m = MyClass(2);
    

    创建一个MyClass 类型的临时对象,使用MyClass 的(默认生成的)复制赋值运算符将其复制到m,然后将其销毁。最终,p 超出范围,其析构函数销毁了指向的 MyClass 实例(绑定到 m 的实例)。

    如果我们明确说明所有隐式调用,就会发生这种情况:

    // std::shared_ptr<MyClass> p(new MyClass(0));
    tmp1.MyClass(0);
    p.shared_ptr(&tmp1);
    
    // MyClass& m = *p;
    p.operator* ();
    
    // m = MyClass(2);
    tmp2.MyClass(2);
    m.operator= (tmp2);
    tmp2.~MyClass();
    
    // p goes out of scope
    p.~shared_ptr();
    tmp1.~MyClass();
    

    【讨论】:

    • 非常感谢您的详尽回答,Angew!
    猜你喜欢
    • 2017-05-02
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 2011-12-20
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多