c++ std::weak_ptr 堆叠对象
c++ std::weak_ptr to stack object
我需要一个指向可能超出范围的堆栈对象的指针。有人告诉我弱指针可以实现这一点,但以下代码会引发段错误:
#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;
}
这是为什么?
编辑
我找到了一个似乎有效的解决方案。
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);
但是评论者告诉我这是未定义的行为。为什么这行得通,为什么是 UB?
edit2
另一位评论者说这是因为共享指针保留在范围内,但如果是这样,为什么它仍然有效?
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);
问题出在这两行代码:
wp = std::shared_ptr<int>(&a, [](auto){});
assert(*wp.lock().get() == 4);
这里你创建一个 std::shared_ptr
,从中初始化 wp
并立即销毁 std::shared_ptr
。在 assert
点,wp
已经过期并且 lock()
returns 为空 std::shared_ptr
。取消引用空指针会导致未定义的行为。
除上述之外,一般的方法是可行的:
{
auto a = 4;
auto sp = std::shared_ptr<int>(&a, [](auto){}); // create a shared_ptr and keep it
wp = sp; // initialize weak_ptr from it
assert(*wp.lock().get() == 4); // sp is still alive, so wp.lock().get() != nullptr
}
我需要一个指向可能超出范围的堆栈对象的指针。有人告诉我弱指针可以实现这一点,但以下代码会引发段错误:
#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;
}
这是为什么?
编辑
我找到了一个似乎有效的解决方案。
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);
但是评论者告诉我这是未定义的行为。为什么这行得通,为什么是 UB?
edit2
另一位评论者说这是因为共享指针保留在范围内,但如果是这样,为什么它仍然有效?
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);
问题出在这两行代码:
wp = std::shared_ptr<int>(&a, [](auto){});
assert(*wp.lock().get() == 4);
这里你创建一个 std::shared_ptr
,从中初始化 wp
并立即销毁 std::shared_ptr
。在 assert
点,wp
已经过期并且 lock()
returns 为空 std::shared_ptr
。取消引用空指针会导致未定义的行为。
除上述之外,一般的方法是可行的:
{
auto a = 4;
auto sp = std::shared_ptr<int>(&a, [](auto){}); // create a shared_ptr and keep it
wp = sp; // initialize weak_ptr from it
assert(*wp.lock().get() == 4); // sp is still alive, so wp.lock().get() != nullptr
}