即使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中的引用很好。
答案 0 :(得分:1)
makeNew
返回指向A
的指针,该指针包含对IntPtr
的引用;但是此IntPtr
已被销毁,它是makeNew
中的局部变量。因此引用无效。
当您将ptr分配给另一个变量时,我认为shared_ptr
引用计数有效,但是当您保留对其的引用时,