【发布时间】:2019-01-16 22:34:04
【问题描述】:
即使 shared_ptr 仍然拥有,对共享指针的引用也会损坏。
我在应用程序中有类似以下代码 sn-p 的内容,并且在尝试使用对类对象内的 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 检查B() -324888 -610139856 主要的() -610139968 -1066293104 intPtrs 大小:1 1 44883
上面是生成的输出,可以在 checkB() 中看到,或者在检查 main() 中新创建的对象时,我得到了垃圾。
因为向量是 IntPtr 的所有者,并且具有持续到程序结束的生命周期,所以我希望 A 中的引用没问题。
【问题讨论】:
-
您是否尝试过使用
asan编译代码和/或使用valgrind运行它? -
您存储了对本地
int_ptr的引用,那么您期望什么?Because the vector is the owner of the IntPtr and has a lifetime that lasts until the program ends, I would expect the reference in A to be fine.向量拥有它自己的shared_ptr实例,这不会让其他实例保持活动状态。
标签: c++11 shared-ptr