我有一个std :: weak_ptr。在尝试使用底层对象之前,我将其锁定以获取shared_ptr:
auto foo_sharedptr = foo_weakptr.lock();
if (foo_sharedptr != nullptr)
{
// do stuff with foo
}
通常这很好用。但是,有时我在锁定调用期间遇到访问冲突:
Unhandled exception at 0x00007FF91F411BC3 (My.dll) in My.exe:
0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
我的猜测是底层指针已被删除,但我对weak_ptr的理解是,在这种情况下,lock应该返回一个nullptr。我在滥用这种类型吗?如果没有,我应该如何调试呢?
答案 0 :(得分:1)
编辑:虽然赞成,但这似乎不是正确答案,对不起:
http://en.cppreference.com/w/cpp/memory/shared_ptr/operator_cmp
template< class T >
bool operator==( const shared_ptr<T>& lhs, std::nullptr_t rhs );
(7) (since C++11)
template< class T >
bool operator!=( const shared_ptr<T>& lhs, std::nullptr_t rhs );
(9) (since C++11)
7)!lhs
9)(bool)lhs
....执行失败?真的不知道。
使用gcc -std = c ++ 11进行测试:(取自http://en.cppreference.com/w/cpp/memory/weak_ptr并改编)
#include <iostream>
#include <memory>
std::weak_ptr<int> gw;
void f()
{
auto spt = gw.lock();
if (spt != nullptr) {
std::cout << *spt << "\n";
}
else {
std::cout << "gw is expired\n";
}
}
int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;
f();
}
f();
}
按预期输出:
42 gw is expired
必须在其他地方
<强>原始强>
简而言之:将其检查为bool,不要与nullptr进行比较(将尝试lhs.get() == rhs.get()
在nullptr上使用rhs = shared_ptr失败):
auto foo_sharedptr = foo_weakptr.lock();
if (foo_sharedptr)
{
// do stuff with foo
}
#include <iostream>
#include <memory>
#include <thread>
void observe(std::weak_ptr<int> weak)
{
std::shared_ptr<int> observe(weak.lock());
if (observe) {
std::cout << "\tobserve() able to lock weak_ptr<>, value=" << *observe << "\n";
} else {
std::cout << "\tobserve() unable to lock weak_ptr<>\n";
}
}
int main()
{
std::weak_ptr<int> weak;
std::cout << "weak_ptr<> not yet initialized\n";
observe(weak);
{
std::shared_ptr<int> shared(new int(42));
weak = shared;
std::cout << "weak_ptr<> initialized with shared_ptr.\n";
observe(weak);
}
std::cout << "shared_ptr<> has been destructed due to scope exit.\n";
observe(weak);
}