I have a std::weak_ptr. Before attempting to use the underlying object, I lock it in order to get a shared_ptr:
auto foo_sharedptr = foo_weakptr.lock();
if (foo_sharedptr != nullptr)
{
// do stuff with foo
}
Usually this works fine. However, sometimes I get an access violation during the call to lock:
Unhandled exception at 0x00007FF91F411BC3 (My.dll) in My.exe:
0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
My guess is that the underlying pointer has been deleted, but my understanding of weak_ptr is that in this case, lock should return a nullptr. Am I misusing the type? If not, how should I approach debugging this?
weak_ptr::lockCreates a new std::shared_ptr that shares ownership of the managed object. If there is no managed object, i.e. *this is empty, then the returned shared_ptr also is empty.
(since C++11) std::weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by std::shared_ptr. It must be converted to std::shared_ptr in order to access the referenced object.
EDIT: Although upvoted, this does not seem to be correct answer, sorry:
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
....broken implementation?? Really don't know.
Test with gcc -std=c++11: (taken from http://en.cppreference.com/w/cpp/memory/weak_ptr and adapted)
#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();
}
Output as expected:
42 gw is expired
Must be elsewhere
Original:
In short: check it as bool, do not compare to nullptr (that will try lhs.get() == rhs.get()
which fails with rhs = shared_ptr on nullptr):
auto foo_sharedptr = foo_weakptr.lock();
if (foo_sharedptr)
{
// do stuff with foo
}
See the documentation:
#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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With