I come from a Java/C# world where I don't worry about memory management. In C++, how do you "clean up" so to speak? I hear of memory leaks from C++ apps all the time, I assume poor memory management is the cause?
I come from a Java/C# world where I don't worry about memory management. In C++, how do you "clean up" so to speak? I hear of memory leaks from C++ apps all the time, I assume poor memory management is the cause?
Anything you allocate with 'new' must be freed once and only once with 'delete'. Anything created with 'new[]' must be destroyed exactly once with 'delete[]'. Whenever you delete a pointer to a base class that actually points to a derived class, and you don't have a virtual destructor, you will have a memory leak.
So in short, it is poor memory management, though good management can sometimes be very hard to achieve. Prefer container like std::auto_ptr or the Boost ( www.boost.org ) smart pointers to raw pointers to help avoid these problems.
The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.
So basically include a virtual destructor for all of my classes? Is there anything similar to a destructor for arrays and anything else I may need to use new for?
There are cases when a virtual destructor is unnecessary, or undesirable, but in general, if you are going to inherit from something, it is probably a good idea to have a virtual destructor. For arrays, use 'delete[]'. For example:
Though, in general, it is wise to prefer std::vector or something similar over arrays.Code:int* a = new int[10]; int* b = new int[10]; delete[] a; // Good delete b; // Very bad... Only frees the memory for the first element.
The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.
Only if your derived class has member data. Adding new functionality (member functions) through inheritance will not cause memory leaks if it is deleted through a base class pointer.Whenever you delete a pointer to a base class that actually points to a derived class, and you don't have a virtual destructor, you will have a memory leak.
No. Making any of your functions virtual in any class along an inheritance chain will add 4 bytes (for a vtable) in every instance of every class that inherits that function. Only use virtual destructors if necessary (and in good practice, they will hardly ever be necessary).So basically include a virtual destructor for all of my classes?
Aside from my beef with virtuals, I agree with everything that Zach said. Prefer pointer wrappers and standard containers to bare pointers and C arrays. (btw, C++ generic containers are MUCH better than Java generic containers)
Actually, I believe that whenever you delete a pointer to a base class that actually points to a derived class, and you don't have a virtual destructor, the behavior is undefined. That includes a situation where the derived class has no data members. I base this on a quote from the standard that I read on another website (I don't have a copy of the standard, so this is really hearsay, but here it is):Originally posted by Zach L.
Whenever you delete a pointer to a base class that actually points to a derived class, and you don't have a virtual destructor, you will have a memory leak.
Originally posted by thefroggy
Only if your derived class has member data. Adding new functionality (member functions) through inheritance will not cause memory leaks if it is deleted through a base class pointer.So in general I wouldn't ever delete a base class pointer to a derived object without a virtual destructor in the base class. Of course, I wouldn't advise deriving from a base class without a virtual destructor in the first place, but that's a discussion for a different thread.In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined.
-----
As far as avoiding memory leaks, I'd also advise creating things on the stack unless you have some reason not to. If you create it on the stack, then you can't forget to delete it. If you have to create an object on the heap, then using smart pointers is definitely a good idea.
I would guess that most memory leaks have nothing to do with virtual destructors. I see them more often when a class has a pointer member variable (using a raw pointer instead of a smart pointer). Or when you have a container of pointers pointing to memory allocated with new. You just have to be vigilant about paying attention to where you allocate memory (with new or new[]) and identifying every place that the object will no longer be needed and can safely be deleted.
For example, if you have member data allocated on the heap, then you should implement a destructor, as well as a copy constructor and operator= (or optionally make the copy constructor and operator= private so they can't be called). Doing this properly will help avoid memory leaks and crashes and other bad memory things.
Though I would have assumed that slicing will only occur when the derived class has member data, I can't argue with the standard if it labels the behavior undefined. I'll have to fish out my copy and take a look.whenever you delete a pointer to a base class that actually points to a derived class, and you don't have a virtual destructor, the behavior is undefined.
Agreed. Though, in the case I mentioned (adding functionality), it wouldn't ever make sense to use a base class pointer anyway.So in general I wouldn't ever delete a base class pointer to a derived object without a virtual destructor in the base class
Does this mean that you find inheritance useful only for polymorphism?Of course, I wouldn't advise deriving from a base class without a virtual destructor in the first place
I think slicing is a rather uncommon manifestation of the undefined behavior, given the way new and delete are implemented.
Same goes for delete with new[], again freeing only the first element is rather improbable.
But discussion is void for both as there's no reason to have either.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
That is primarily what I was getting at (though for some reason, not saying).Originally posted by thefroggy
Only if your derived class has member data. Adding new functionality (member functions) through inheritance will not cause memory leaks if it is deleted through a base class pointer.
On second thought though, I imagine that it probably is undefined according to the standard. At any rate, it is unwise to delete a pointer to a base class that (possibly) points to a derived class is there is no virtual destructor in the base class. Similarly, be careful to use 'delete[]' where appropriate.
The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.
Not necessarily. But in many cases it would make just as much sense, if not more, to make global functions that do whatever you are trying to do rather than derive for the sake of adding functionality. In other cases, deriving the class is easier and it doesn't make sense to create global functions, but in those cases I would make sure the base class destructor was virtual just in case. If the extra 4 bytes is important, then I'd go the route of the global function or containment.Originally posted by thefroggy
Does this mean that you find inheritance useful only for polymorphism?