C++ c++;std::堆栈对象的弱\u ptr
我需要一个指向可能超出范围的堆栈对象的指针。我被告知弱指针可以实现这一点,但以下代码抛出seg错误:C++ c++;std::堆栈对象的弱\u ptr,c++,smart-pointers,C++,Smart Pointers,我需要一个指向可能超出范围的堆栈对象的指针。我被告知弱指针可以实现这一点,但以下代码抛出seg错误: #include <memory> #include <cassert> int main() { std::weak_ptr<int> wp; { auto a = 4; wp = std::shared_ptr<int>(&a, [](auto){}); assert
#include <memory>
#include <cassert>
int main()
{
std::weak_ptr<int> wp;
{
auto a = 4;
wp = std::shared_ptr<int>(&a, [](auto){});
assert(*wp.lock().get() == 4);
}
assert(wp.lock().get() == nullptr);
return 0;
}
#包括
#包括
int main()
{
标准:弱ptr wp;
{
自动a=4;
wp=std::shared_ptr(&a,[](自动){});
断言(*wp.lock().get()==4);
}
断言(wp.lock().get()==nullptr);
返回0;
}
为什么会这样
编辑
我找到了一个似乎有效的解决办法
std::weak_ptr<int> wp;
{
auto a = 4;
auto sp = std::shared_ptr<int>(&a, [](auto){});
wp = sp;
assert(*wp.lock().get() == 4);
}
assert(wp.lock().get() == nullptr);
std::弱可湿性粉剂;
{
自动a=4;
auto sp=std::shared_ptr(&a,[](auto){});
wp=sp;
断言(*wp.lock().get()==4);
}
断言(wp.lock().get()==nullptr);
但一位评论员告诉我,这是一种未定义的行为。为什么会这样,为什么会这样
编辑2
另一位评论者说,这是因为共享指针保持在范围内,但如果是这样,为什么这仍然有效
std::weak_ptr<int> wp;
{
auto a = 4;
auto sp = std::shared_ptr<int>();
{
sp = std::shared_ptr<int>(&a, [](auto){});
wp = sp;
assert(*wp.lock().get() == 4);
} //shared pointer out of scope
assert(*wp.lock().get() == 4);
} // stack object out of scope
assert(wp.lock().get() == nullptr);
std::弱可湿性粉剂;
{
自动a=4;
自动sp=std::shared_ptr();
{
sp=std::shared_ptr(&a,[](自动){});
wp=sp;
断言(*wp.lock().get()==4);
}//共享指针超出范围
断言(*wp.lock().get()==4);
}//堆栈对象超出范围
断言(wp.lock().get()==nullptr);
问题在于这两行代码:
wp = std::shared_ptr<int>(&a, [](auto){});
assert(*wp.lock().get() == 4);
问题在于这两行代码:
wp = std::shared_ptr<int>(&a, [](auto){});
assert(*wp.lock().get() == 4);
shared_ptr
用于跟踪所指向变量的生存期。它通过假设自己的生命周期相同来实现这一点。但在第一个示例中,std::shared_ptr会立即被销毁。请小心使用此解决方案。通常假设std::shared_ptr
可以非常安全地复制和传递。这是他们的主要优势。有人很容易尝试使用共享的\u ptr
来破坏您正在尝试的操作。事实上,似乎很难想象一个函数需要一个共享的\u ptr
,而不尝试移动或复制它,这将打破这种方法。编辑:在我看来,这个解决方案似乎是在试图解决非常糟糕的设计决策。这是一个很好的解决方案。请描述:您的代码应该解决的问题,而不是如何修复您的问题解决方案。在第三个示例中,共享的ptr在第二次断言之后超出范围,而不是在第一次断言之后,如代码中的注释所示。这就是代码仍然有效的原因。共享\u ptr的生存期由分配给它的sp
变量定义,而不是由调用shared\u ptr()
构造函数的块定义。“我需要一个指向可能超出范围的堆栈对象的指针。”首先让共享\u ptr持有的对象,而不是试图将shared_ptr和weak_ptr包装在基于堆栈的对象周围。shared_ptr
的工作是跟踪它所指向的变量的生存期。它通过假设自己的生命周期相同来实现这一点。但在第一个示例中,std::shared_ptr会立即被销毁。请小心使用此解决方案。通常假设std::shared_ptr
可以非常安全地复制和传递。这是他们的主要优势。有人很容易尝试使用共享的\u ptr
来破坏您正在尝试的操作。事实上,似乎很难想象一个函数需要一个共享的\u ptr
,而不尝试移动或复制它,这将打破这种方法。编辑:在我看来,这个解决方案似乎是在试图解决非常糟糕的设计决策。这是一个很好的解决方案。请描述:您的代码应该解决的问题,而不是如何修复您的问题解决方案。在第三个示例中,共享的ptr在第二次断言之后超出范围,而不是在第一次断言之后,如代码中的注释所示。这就是代码仍然有效的原因。共享\u ptr的生存期由分配给它的sp
变量定义,而不是由调用shared\u ptr()
构造函数的块定义。“我需要一个指向可能超出范围的堆栈对象的指针。”首先让共享\u ptr持有的对象,而不是试图围绕基于堆栈的对象包装共享的\u ptr和弱的\u ptr。