C++ Do I need a destructor in this class?


mjohansson

Supporter
Joined
Feb 10, 2011
Messages
409
class A{

public:

int whatever;

};

class Z{

public:

A *hmm;

Z *eeh;

};

What happens to a Z object, will the members of type A and Z cause memory leak?

So a class has a default destructor that takes care of business so the members in a Z object don't remain when program exits?

Im very insecure about this and can't find the specific answer.
 
If an object of the class owns resources, it should release those resources when it is destructed. In this case it depends entirely on if an object of type Z owns the data behind the A and Z pointers or merely holds a reference to them. The pointer-type members themselves do not leak memory, but the things they point to may not be freed unless someone else holding pointers to that same data does it. When a program exits all its resources are freed so you don't have to worry about what happens then.
 
Last edited by a moderator:
Was referencing Z within Z intentional? Even you can do this its not a good idea.

If you ran this code:


Z foo;

foo.hmm = new A();
foo.eeh = new Z();

You at some point need to delete the reference to A and Z. This could happen anywhere in your code. It usually makes sense to do it with the destructor.


Z foo;
Z minorZ_foo;
A minorA_foo;

foo.hmm = &minorA_foo;
foo.eeh = &minorZ_foo;

if you did like so I dont think you leak anything since everything is allocated on the stack.
 
Last edited by a moderator:
If you ran this code:

Z foo;

foo.A = new A();
foo.Z = new Z();

You at some point need to delete the reference to A and Z. This could happen anywhere in your code. It usually makes sense to do it with the destructor.
You've instantiated those instances yourself; isn't it your responsibility to delete them?  If Z's constructor declared A=new A() then its destructor ought to delete it, but in this case I'm not sure it's Z's job.
 
What I want is to have a pointer to other objects of same class, my actual code is an array of pointers, I could have an external array of pointers for my purpose but I thought it was more clean to not have external variables needed for my functions processing. Thats why I had Z *eeh; inside class Z. 

So how about if I did this:

A reference_1;

Z object_1,object_2;

boject_1.hmm=&reference_1;

object_2.eeh=&object_1;

And then exit program, will any memory now remain unavailable for OS? Im currently under the impression there shouldn't be. No dynamic allocation should have happened, and a pointer holds an adress and that can't affect the memory of the adress in question? Like the reference_1 object should still be automatically deleted at program exit?
 
The short answer would be, no. If this is really all there is to Z, it won't cause a memory leak.

Of course, this highly depends on how Z is actually used in your particular case.

Looking at the code, this seems to be a singly linked list of A instances (which I assume is abbreviated) which may contain "holes" represented as null pointers. If that is the case, and A values are always allocated via new, I'd recommend making the ownership explicit by using std::unique_ptr<A> (from C++11 on or if TR1 is available) or std::auto_ptr<A> (before C++11). You don't even need to define a destructor that way, because the default one will do what you need.

If the list does not contain any holes (i.e. hmm is never NULL/nullptr/0/whatever the trend for invalid pointers is this year) I' say, why not scrap the Z class altogether and use a std::forward_list<A> (C++11!) or std::list<A> instead. This conversion will only work fully if Z and its corresponding A are always created together.

If on the other hand, an instance of A may be shared by multiple Zs, neither the list nor the owning pointer approach will work. You'd have to use a std::shared_ptr<A> (possibly in a list/forward_list) instead, which allows multiple pointers to the same object. This is only available in C++11 though. A boost::shared_ptr may serve you as an alternative if you don't mind the boost dependency.

Addition after new post #5 while I wrote this:

That way, no memory is lost since de/allocation is handled by the compiler. And if you're on a relatively modern OS, even dynamically allocated memory will not remain unavailable, since they keep track of who allocated what and reclaim it when the process terminates.
 
The OS should tidy up any memory a program uses if you exit it.  It's mainly for long-running programs that memory leaks are a real issue, though of course it's good practice to make any code you write tight against leaks in case you decide to reuse it later.
 
Thanks for the help guys, Im gonna keep doing what Im doing. My system got really slow lately and then I read something but don't remember what and I thought I had caused a memory leak, but I had changed the code from how it was before and I can't remember exactly what I did now, but maybe system just got slow for other reasons, I never shut it down and never reboot until the OS keeps complaining to much that I need to update it... 

Anyway, I will release the source code along with my games so we will see what people have to say about my code then... :)
 
Wouldn't the garbage collection help assuming all references (pointers) to said instance have gone out of scope or been removed?
 
In C# (or Java where that came from) sure, but there is no garbage collector in C++ unless you roll your own, or use a library implementation.

C++ will automatically delete anything declared on the stack when the scope exits, but anything you declare on the heap (via 'new') is up to you to delete, unless you use one of these fancy newfangled unique_ptr objects, which AIUI makes something on the heap behave like something on the stack, and get automatically deleted when you leave the scope you declared the unique_ptr in (function definition, class, file, what have you).

Having a true reference counting garbage collector means you can take a reference to that object elsewhere, and it won't be deleted until everyone stops using it, rather than it becoming invalid as soon as the invoking function etc. completes.  In C++ you must copy the object if you want to keep it (and then it becomes your responsibility as the creator of that copy to delete it when done).
 
For fun, you could also consider boost::shared_ptr (using the Boost library). With a shared pointer, it will take care of freeing the memory for you.

As it sounds like you are learning the ropes, I'd probably recommend continuing in the direction you currently are (experimenting, learning about how to manage memory yourself, what should be responsible for freeing, etc.) as you'll learn a lot of important information that way. But then further down the line, using constructs that handle memory for you maybe a better way to go.
 
Back
Top