0

I am beginning to teach myself C++ and how to handle objects without a garbage collector is causing me some confusion. Here is a simple case of what I am trying to do:

A* a;
B b = new B(a);    // Note that B is a derived class of A
a = &b;

while (a != NULL)
{
    (*a).run();
}

This all works as I expect it to. Where I am having the issue, is that inside the run() method of B, I want to do something like:

C c = new C(a);  // a is the same pointer as above, that has been stored 
                 // and C another derived class from A
a = &c;

and then let run() exit. The while loop in the first block would then call would call run() on the new object. My question is, how do I make sure that the memory from the original b is correctly de-allocated?

Godric Seer
  • 359
  • 4
  • 16
  • You don't need to allocate everything via `new`. It's perfectly fine (and actually preferable) to just declare the variable like so: `B b;` or `C c;`. If the object needs to exist outside its current scope, use [smart pointers](http://stackoverflow.com/questions/395123/raii-and-smart-pointers-in-c). – In silico Jan 05 '13 at 21:47
  • Most of the above code fails to compile. In C++ objects and pointers to objects are not the same. – Yakk - Adam Nevraumont Jan 05 '13 at 22:09
  • I have found that I was greatly overcomplicating what I was trying to do. I simply made run() return type A and am avoiding pointers altogether. Considering I asked about deallocation though, the answers were insightful. @Yakk, what were the errors? – Godric Seer Jan 05 '13 at 22:13

2 Answers2

1

Whenever you're faced with dynamic memory allocation and nontrivial ownership semantics, smart pointers are often a good way to ensure correctness.

See, for example, std::shared_ptr.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

You could use std::shared_ptr in this case. If two classes have members which need to point to the same object, then you can make both of them shared_ptr. And you do this usually, however if while doing so, if you about to create cyclic-dependency, then to break that cyclic-dependency, you need std::weak_ptr.

Here is example of std::shared_ptr and std::weak_ptr.

WRONG CODE (cyclic-dependency):

struct B;

struct A
{
   std::shared_ptr<B> bp;
}

struct B
{
   std::shared_ptr<A> ba;  //this creates a cyclic dependency.
}

CORRECT CODE (non-cyclic):

struct B;

struct A
{
   std::shared_ptr<B> bp;
}

struct B
{
   std::weak_ptr<A> ba;  //break cyclic dependency with std::weak_ptr
}
Nawaz
  • 353,942
  • 115
  • 666
  • 851