Shared Pointers using std::shared_ptr

Shared Pointer Cyclic References

What happens if two shared pointers reference each other? Will this cause a memory leak?

Illustration representing computer hardware

If two shared pointers reference each other, it will create a cyclic reference, which will prevent the objects from being deleted and will cause a memory leak.

Consider this example:

#include <memory>

class Node {
public:
  std::shared_ptr<Node> next;
};

int main() {
  auto node1 = std::make_shared<Node>();
  auto node2 = std::make_shared<Node>();

  node1->next = node2;
  node2->next = node1;
}

In this code, node1 and node2 are shared pointers to Nodeobjects. The Node objects contain a shared_ptr member variable next, which is used to make node1 point to node2, and node2 point back to node1.

The problem is that when main ends, node1 and node2 will be destroyed. However, their destructor won't delete the Node objects they point to, because each Node object is still referenced by the other Node's next pointer.

As a result, the memory for these Node objects will never be freed, causing a memory leak.

To solve this problem, we can use weak pointers (std::weak_ptr). A weak pointer is a non-owning reference to an object managed by a shared pointer. It doesn't contribute to the reference count, so it doesn't prevent the object from being deleted.

Here's how we could use weak pointers to avoid the cyclic reference:

#include <memory>

class Node {
public:
  std::weak_ptr<Node> next;
};

int main() {
  auto node1 = std::make_shared<Node>();
  auto node2 = std::make_shared<Node>();

  node1->next = node2;
  node2->next = node1;
}

Now, when node1 and node2 are destroyed, the Node objects they point to will also be deleted, because the weak pointers in the next members don't prevent the reference count from reaching zero.

However, using weak pointers comes with its own set of challenges. Because a weak pointer doesn't guarantee that the object it points to still exists, you have to convert it to a shared pointer before you can use it, and you have to check that the conversion succeeded.

This adds some complexity to the code, but it's necessary to avoid memory leaks in structures that could contain cyclic references, like graphs or trees.

Answers to questions are automatically generated and may not have been reviewed.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved