对共享指针的引用已损坏

时间:2019-01-16 22:34:05

标签: c++11 shared-ptr

即使shared_ptr仍然拥有,对共享指针的引用也已损坏。

我在应用程序中有类似以下代码段的内容,并且在尝试使用对类对象内部的shared_ptr的引用时,会不断获得指向指针的悬挂引用或某些其他损坏。以下基准测试在使用gcc 5.4.0的RHEL7上也存在相同的问题。它也发生在clang 4.0.1中。我已经验证了shared_ptr直到系统退出之前才真正破坏指向对象的对象。

在A中存储shared_ptr时,一切正常。

#include <cassert>
#include <iostream>
#include <memory>
#include <vector>

using namespace std;

class Int
{
  public:
    Int() : Int(0) { }
    Int(int v) : _val(v) { }
    int val() const { return _val; }
    ~Int() { }

  private:
    int _val;
};

typedef shared_ptr<Int> IntPtr;

class A
{
  public:
    IntPtr &intPtr;
    A() = delete;
    A(IntPtr &int_ptr) : intPtr(int_ptr)
    {
        cout << "A()" << endl;
        cout << intPtr.use_count() << endl;
        cout << intPtr->val() << endl;
    }
};

class B
{
  public:
    B(A *a) : _a(a) { }
    B() = delete;
    A *_a;
};

vector<IntPtr> intPtrs;

A* makeNew()
{
    IntPtr int_ptr = make_shared<Int>(44883);
    intPtrs.push_back(int_ptr);
    cout << "makeNew()" << endl;
    cout << intPtrs.back().use_count() << endl;
    cout << intPtrs.back()->val() << endl;
    A *a = new A(int_ptr);

    return a;
}

void checkB(B *b)
{
    A *a = b->_a;
    assert(a);
    cout << "checkB()" << endl;
    cout << a->intPtr.use_count() << endl;
    cout << a->intPtr->val() << endl;
}

int main(int argc, char *argv[])
{
    B *b = new B(makeNew());
    checkB(b);
    cout << "main()" << endl;
    A *a = b->_a;
    cout << a->intPtr.use_count() << endl;
    cout << a->intPtr->val() << endl;

    cout << "intPtrs size: " << intPtrs.size() << endl;

    for (const auto &int_ptr : intPtrs) {
        cout << int_ptr.use_count() << endl;
        cout << int_ptr->val() << endl;
    }

    return 0;
}

makeNew() 2 44883 一种() 2 44883 checkB() -324888 -610139856 主要() -610139968 -1066293104 intPtrs大小:1 1个 44883

上面是生成的输出,可以在checkB()或在main()中检查新创建的对象时看到,我得到了垃圾。

由于向量是IntPtr的所有者,并且生命周期可以一直持续到程序结束,因此我希望A中的引用很好。

1 个答案:

答案 0 :(得分:1)

makeNew返回指向A的指针,该指针包含对IntPtr的引用;但是此IntPtr已被销毁,它是makeNew中的局部变量。因此引用无效。

当您将ptr分配给另一个变量时,我认为shared_ptr引用计数有效,但是当您保留对其的引用时,