sil*_*twf 4 c++ smart-pointers weak-ptr
我是智能指针的新手,我试图绕过我的脑袋,为什么在取消引用运算符之后weak_ptr会过期.我以前测试的代码在这里:
#include <memory>
#include <iostream>
#include <vector>
using namespace std;
struct node
{
weak_ptr<node> parent;
shared_ptr<node> child;
int val;
};
shared_ptr<node> foo()
{
shared_ptr<node> a = make_shared<node>();
shared_ptr<node> b = make_shared<node>();
a->val = 30;
b->val = 20;
b->parent = a;
a->child = b;
return a;
}
int main()
{
shared_ptr<node> c = foo();
node d = *foo();
if (c->child->parent.expired())
{
cout << "weak ptr in c has expired." << endl;
}
if (d.child->parent.expired())
{
cout << "weak ptr in d has expired." << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该计划的产出 weak ptr in d has expired.
我不明白为什么当d使用dereference运算符时,它会过期.关于这一点,无论如何要防止它(除了不解除引用)?
我尝试通过更改in节点建议mrtnjweak_ptr,shared_ptr但我认为我有内存泄漏.我将node班级改为
struct node
{
shared_ptr<node> parent;
shared_ptr<node> child;
int val;
};
Run Code Online (Sandbox Code Playgroud)
然后修改源代码以添加tryCreate功能.
void tryCreate()
{
node d = *foo();
}
Run Code Online (Sandbox Code Playgroud)
然后在我main这样称呼它,使我的主要看起来像
int main()
{
tryCreate();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用Visual Studio 2015的内存分析,并注意到只有分配,没有解除分配.我变成parent了一个weak_ptr,我看到了deallocations.我做错了什么,或者确实要求weak_ptr在这些循环条件下使用?
一个weak_ptr当最后到期shared_ptr是指对象,被销毁.
在您的语句中发生的代码中
node d = *foo();
Run Code Online (Sandbox Code Playgroud)
这里foo()返回一个shared_ptr,它是shared_ptr引用该对象的最后一个(由两个创建的父对象foo).shared_ptr在derefencing之后,这是一个在那里被摧毁的临时性.这会将引用计数减少到0并且weak_ptr到期.
由于它shared_ptr是最后一个,因此对象被销毁,这导致其子对象也被销毁.因此,深入研究这些对象的后续代码具有未定义的行为.
由于d包含a shared_ptr到子节点,因此此时子节点不会被销毁,正如Miles Budnek在评论中所指出的那样.
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |