Ссылка на общий указатель повреждается, даже если shared_ptr все еще принадлежит.
У меня есть что-то вроде следующего фрагмента кода в приложении, и я продолжаю получать свисающие ссылки на указатели или некоторые другие искажения при попытке использовать ссылки на shared_ptr внутри объекта класса. Приведенный ниже тест также показывает ту же проблему на RHEL7 с использованием gcc 5.4.0. Так же бывает и с clang 4.0.1. Я убедился, что shared_ptr никогда не разрушает указанный объект до тех пор, пока система не выйдет.
При хранении shared_ptr в A все работает просто отлично.
#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 будет в порядке.