venkysmarty
venkysmarty

Reputation: 11431

circular reference memory leak in C++

I am reading safe C++ and author mentioned about circular reference as below.

Consider two objects containing pointers to each other

class A;

class B { public: A* a; };

class A { public: B* b; };

This situation is known as a "circular reference". Pointers exist to A and to B, but if there are no ohter pointers to atleast one of these objects from somewhere else, there is no way to reclaim the memory for either variable and therefore you create a memory leak. These two objects will live happily ever after and never be destroyed.

My question

  1. Why there is memory leak? Why is it bad idea to delete memory in destructor of corresponding class?
  2. On what basis author mentioned that two objects live ever after?

Thanks for your time and help

Upvotes: 0

Views: 1238

Answers (2)

James Kanze
James Kanze

Reputation: 153967

The concept in question is reachability. Basically, starting from a base set of pointers (active variables, etc.), can you reach the object in question, directly or indirectly. If not, the object is unreachable.

A trivial example of an unreachable object is one to which there is no pointer. The circular reference example is another example: there are pointers to both of the objects in question, but the objects are still not reachable.

In most languages, if an object is unreachable, it will be garbage collected, sooner or later. In C++, you are required to explicitly delete any dynamically allocated object before it becomes unreachable; otherwise, you can never delete it (and memory has leaked). One frequent C++ technique for simulating garbage collection is reference counted pointers; this technique (unlike other garbage collection techniques) does not handle circular references correctly, and will thus leak memory.

While C++ would benefit from garbage collection, it's important to realize that this is not as much an issue in C++ as in most other languages. In C++, dynamically allocated objects usually only correspond to objects which have defined lifetimes, and which will be destructed explicitly in response to some external events (or which will never be destructed, because once the program has finished with them, the program has finished, period—think of the parse tree in a compiler). Because C++ supports value semantics, most other objects are not dynamically allocated, but are rather local variables, or data members of a larger object, and have their lifetime automatically managed. Although C++ has a number of “smart” pointers to automatically manage deleting memory, if you find yourself drawn to using them extensively, you're probably abusing dynamic allocation.

Upvotes: 0

Steve Jessop
Steve Jessop

Reputation: 279305

There are some garbage collection algorithms sufficiently simple that they would fail to collect two unreachable objects that reference each other (basically, if the gc uses reference-counting only).

However, C++ doesn't guarantee to provide any garbage collection at all. And the code you have shown doesn't even use reference counting. So as far as what you show is concerned, the reason that objects are leaked (if any objects are leaked) is nothing to do with circular references, it's because you didn't free them.

It seems likely that the book you reference is speaking in the context of some additional information that you have chosen not to show in this question -- probably there's some reference-counting in the book.

Upvotes: 4

Related Questions