1

Here are the things I know about smart pointers

  1. shared_ptr is a smart pointer such that multiple shared_ptr can point to an object in the heap. Even if one of the shared_ptr is deleted the object in the heap will not be destroyed as long as it's reference count is above zero.
  2. a weak_ptr also points to an object in the heap but it does not increases the reference count of that object
  3. we can use weak_ptr to break circular reference

In the case of Doubly Linked Lists we have two pointers to point to the previous and the next node. We use a shared_ptr and a weak_ptr in the implementation. Why don't we use two weak_ptr ?

Gauranga Das
  • 19
  • 1
  • 3

2 Answers2

5

We don't use two weak_ptr because it wouldn't work.

Imagine a list with two nodes. The list head is a non-weak ptr to the first node. So the first node stays alive. But what non-weak pointer keeps the second node alive?

There are two challenges to managing the lifetime of objects. They should stay alive long enough, but not too long. This is not just for C++ or smart pointers, this is a basic problem in virtually all programming languages. You solve it by understanding the problem you're working on, and expressing that problem in the tools that your language gives you.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • I see. Let's say we have a Doubly Linked List of 10 elements such that the both the previous and next pointers are weak_ptr. If some other pointer points to 5th node and the pointer is deleted. The node it is pointing to is also destroyed and therefore, we won't be able to access the elements after the 5th element. But, if we use a shared_ptr that 5th node will be protected from destruction. Is this what you are trying to say ? – Gauranga Das Sep 03 '18 at 00:52
  • @GaurangaDas: The premise is flawed. Since we don't have a pointer keeping other elements alive, the list won't have 10 elements to start with. We'd have two elements (first and "fifth") which do not form a list. – MSalters Sep 03 '18 at 07:11
3

We could use a shared_ptr to next and weak_ptr to prev, but not two weak_ptr. If there is no shared_ptr that points to a node, then the reference count become zero, and the weak_ptr becomes nullptr.

Anyway, using a shared_ptr for linked lists is an overkill. Since only one object owns the node (the head, or the previous node), a simple unique_ptr for next will do, with a raw pointer to prev.

Note that using smart pointers is risky with linked lists. The problem comes up when a long list is being destructed, it is being destructed recursively. Node destructor calls smart pointer's destructor, which calls node destructor. Most likely the stacj will grow in O(n). Since a list can be longer than the maximum possible stack, the code may run out of stack space and crash.

This does not mean that smart pointers can't be used, only that the node has to implement a destructor. The destructor has to erase nodes in a loop, so that recursion won't be invoked.

Michael Veksler
  • 8,217
  • 1
  • 20
  • 33