Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between raw pointer and weak_ptr?

As in title. This question probably already has an answer but I failed to find one.

like image 668
NPS Avatar asked May 26 '13 14:05

NPS


People also ask

What pointer is weak_ptr similar to?

A weak_ptr is created as a copy of shared_ptr.

When should I use weak_ptr?

By using a weak_ptr , you can create a shared_ptr that joins to an existing set of related instances, but only if the underlying memory resource is still valid. A weak_ptr itself does not participate in the reference counting, and therefore, it cannot prevent the reference count from going to zero.

What is a raw pointer?

A raw pointer is a pointer whose lifetime isn't controlled by an encapsulating object, such as a smart pointer. A raw pointer can be assigned the address of another non-pointer variable, or it can be assigned a value of nullptr . A pointer that hasn't been assigned a value contains random data.

What is a weak_ptr in C++?

template< class T > class weak_ptr; (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.


2 Answers

The fundamental conceptual difference between a naked pointer and a weak_ptr is that if the object pointed to is destroyed, the naked pointer won't tell you about it. This is called a dangling pointer: a pointer to an object that doesn't exist. They're generally hard to track down.

The weak_ptr will. In order to use a weak_ptr, you must first convert it into a shared_ptr. And if that shared_ptr doesn't point to anything, then the object was deleted.

For example:

#include <iostream> #include <memory>  std::weak_ptr<int> wp;  void test() {     auto spt = wp.lock(); // Has to be copied into a shared_ptr before usage     if (spt) {         std::cout << *spt << "\n";     } else {         std::cout << "wp is expired\n";     } }  int main() {     {         auto sp = std::make_shared<int>(42);         wp = sp;         test();     }     test(); } 

Output

42 wp is expired 
like image 118
Nicol Bolas Avatar answered Oct 04 '22 05:10

Nicol Bolas


A raw pointer is (at least normally) simply an address. You can't tell anything about what it points at from the pointer itself.

A weak_ptr is always associated with a shared_ptr, so we probably need to start with a shared_ptr to make any sense of a weak_ptr.

A shared_ptr is reference counted, so it keeps track of how many references (pointers) to an object exist, and automatically destroys the object when no more references to that object exist.

As I already said, a weak_ptr is associated with a shared_ptr. Unlike a shared_ptr, the existence of a weak_ptr does not increment the reference count for the pointee object. To use a weak_ptr, you must first convert it to a shared_ptr. If the current reference count is positive, that will succeed, and converting the weak_ptr to a shared_ptr will increment the reference count to signify that the converted pointer is a "real" reference to the object. If, on the other hand, the reference count is already zero (meaning the pointee object has already been destroyed) the attempt to convert the weak_ptr to a shared_ptr will simply fail.

A shared_ptr means shared ownership of the pointee object. The pointee object will remain in existence as long as at least one shared_ptr to that object exists, but as soon as the last shared_ptr to the object is destroyed, so will the pointee object.

A weak_ptr means non-owning access to the pointee object. It allows access if the object exists. If the object has been destroyed, it tells you that the pointee object no longer exists rather than attempting to access the destroyed object.

like image 28
Jerry Coffin Avatar answered Oct 04 '22 04:10

Jerry Coffin