How to free memory in my Class destructor?
Solution 1
Your class members do not look to be dynamically allocated, in which case you don't need to explicitly delete
anything in the destructor. If you happened to leave out some pointers to allocated memory, in this question, which you allocate with new
, you would need to delete
these in the destructor.
Remember, if you new
you need to delete
, similarly with new[]
-delete[]
. Barring the case of allocation to a std::unique_ptr
.
If your MyClass
objects themselves are allocated on the heap with new
, then you would have to delete
them.
p.s. if you are using C++11, you should probably use std::array
now.
From your new code, it is obvious that whoever keeps the list returned from getListOfObjects()
, needs to call delete
on each element when its to be destroyed. It is likely the destructor of SomeOtherClass
.
Alternatively you can wrap the MyClass*
pointers within a std::unique_ptr
or std::shared_ptr
(or any of the boost smart pointers which might be relevant here) which would then delete automatically when the vector holding them goes out of scope and is destroyed.
If doSth
is accurate in its representation, and ensures that ALL instances of MyClass
get delete
d, then this code seems fine, from a memory leak standpoint.
Solution 2
All I see is a class that correctly manages it's memory. boost::array
is a fancy wrapper over plain old array (boost::array<int,64> arrA
is just int arrA[64]
with methods added to make it a random-access read-only collection for standard library algorithms) and as such is allocated as part of the object.
Now if you say you have a leak, you apparently do mismanage memory somewhere, but it's not here.
In modern C++, it's trend to avoid writing the deletes yourself, leaving it up to specialized destructors instead. Given the allocating code above, the Boost.Pointer Container might be the right tool.
Solution 3
What I see is all allocated on stack. so they are being properly managed and well deleted in destructor. If there is a memory leak, may be you are calling new MyClass
but not releasing them. or something elsewhere.
as I see in edited code there is a vector are you deleting the items of objects
returned by SomeOtherClass::getListOfObjects
?
also you may use boost::shared_ptr<MyClass>
instead of raw pointers MyClass*
.
Solution 4
This sounds a bit odd
My principal class (of which I'm creating some millions of instances (which hopefully are automatically deleted, since they stop being used)
If you are creating instances of MyClass
and have not done it using smart pointers of some kind then they will not magically be deleted, you need to do the job.
Related videos on Youtube
Dr.Kameleon
The Arturo Programming Language Who am I? A Greek-born Spain-based programmer and former Med-student, who has been in love with the Art of Code since he was a 7-year-old kid and would not change it for anything in this world. Current Position : Chief Software Architect & Founder @ InSili.co Expertise C / D / Nim Flex / Bison Objective-C / Cocoa Swift Ruby LaTeX HTML / CSS JavaScript / Node.js PHP / SQL CodeIgniter / Wordpress Also playing with : Assembly C++ Haskell Perl Pascal / Delphi Prolog Programming Interests Low-level engineering: compilers, interpreters, programming languages, operating system kernels macOS/Cocoa development Chess engines Data extraction, scraping and automation Website design & development Typesetting & e-publishing Projects Open-Source: Arturo - Programming language & Bytecode Stack-based VM interpreter -- in Nim/C Delicious - A library of Swift language extensions and Cocoa utilities for macOS/iOS -- in Swift Logramm - Programming language & Interpreter -- in D MathMachine - A Math-Oriented programming language & Interpreter -- in C++ Bogart - A chess engine project -- in C++ FoldWatcher - A (rather ancient) Folding@Home GUI Client -- in C++/Qt Nemesis - A (rather ancient too) Remote Desktop Client-Server app -- in Pascal/Delphi & various more... Commercial: iSwift - An Objective-C to Swift converter & various Swift-related resources Peppermint - Code editor for macOS Squeezer - Resource-compression app for HTML/CSS/JS/images for macOS JSON Wizard - JSON viewer & editor for macOS & various more... Books: Swift 4 recipes - Hundreds of Useful Hand-picked Code Snippets -- by Apress & many self-published under the publishing label Fluo~
Updated on June 04, 2022Comments
-
Dr.Kameleon almost 2 years
OK, I suppose this question may sound too silly, but memory-management (especially in C/C++) has never been my strong point and since it's usually not a noticeable thing, I tend to overlook it. So, forgive me if all this sounds stupid. However, since my current project involves A LOT of data and processing, memory consumption easily goes above 2GB in a matter of seconds and it definitely slows the whole thing down, so... it's time I started thinking of ways how to fix it.
So, here is my situation...
My principal class (of which I'm creating some millions of instances (which hopefully are automatically deleted, since they stop being used), so supposedly this is the culprit) is (roughly) this :
class MyClass { public: // My Constructors MyClass (); MyClass (std::string param); // My Destructor (still empty) virtual ~MyClass (); // Some methods void methodA(std::string moves); void methodB(); //---------------------- // My Variables //---------------------- boost::array<int,64> arrA; boost::array<unsigned int,13> arrB; unsigned int key; boost::array<int,3> arrC; int argA; int argB; };
And this is (roughly - actual code has been altered) how the instances of the above class are created :
vector<MyClass*> SomeOtherClass::getListOfObjects() { vector<MyClass*> objects; for (int i=0; i<MAX_OBJS; i++) { // Do some preparatory work objects += new MyClass(); } return objects; }
And here's how the results of the above function are being used :
void SomeOtherClass::doSth() { vector<MyClass*> objs = this->getListOfObjects(); int objsSize = objs.size(); for (int i=0; i<objsSize; i++) { MyClass* obj = objs[i]; // Do sth with obj delete objs[i]; } }
So, my question is :
What should I do in my destructor, so that when the object is not needed anymore and thus released, all of its "subcomponents" are released too? (e.g. the 2
boost::array
s)Is there anything wrong you notice with the approach above?
Please let me know if there's anything else you need to know about my implementation...
-
Seng Cheong over 11 years
"it's usually not a noticeable thing, I tend to overlook it."
-- Worst attitude ever. Are you familiar with thedelete
keyword? -
BЈовић over 11 yearsyou are missing copy/move constructors
-
Dr.Kameleon over 11 years@JonathonReinhart I know, I know; but you know how these things are...
-
johnbakers over 11 yearsDoesn't the question depend on whether your components are allocated on the stack or the heap?
-
Seng Cheong over 11 years@Dr.Kameleon Right, and that's the reason modern software hogs huge amounts of memory and crashes. "If something is worth doing, it's worth doing right."
-
Dr.Kameleon over 11 years@JonathonReinhart How's
delete
applicable toboost::array
? -
Jesse Good over 11 yearsThere is no memory to be managed in your class. How many of these
MyClass
objects are you making? -
Dr.Kameleon over 11 years@JesseGood Around 100 millions per second (lol). True.
-
Jan Hudec over 11 years@Dr.Kameleon: I don't think any current memory allocator on current hardware could achieve that speed. Not to mention that the object has at least 336 bytes, so 100 millions are 33.6 GB and that does not fit to memory on common computer today.
-
Dr.Kameleon over 11 years@JanHudec On a common computer. Not one with a 64GB memory on it. ;-)
-
billz over 11 years@Dr.Kameleon what's value of MAX_OBJS? and do you call getListOfObjects() a lot or just once?
-
Dr.Kameleon over 11 years@billz I don't think the answer is relevant (since the code above is an example of what the original code is), but if it matters at all it is somewhere near 12.
-
juanchopanza over 11 yearsAnd how do you
delete
the objects in thevector<MyClass*>
? BTWstd::vector
has nooperator +=
. -
Dr.Kameleon over 11 years@juanchopanza Boost supports it (
#include <boost/assign/std/vector.hpp>
). After the function has been called, and looped through all of the results, I either tried relooping and deleting or deleting after each iteration, but still keep getting the same error :malloc: *** error for object 0xSOME_MEMORY_ADDRESS: pointer being freed was not allocated
. -
Bernhard Barker over 11 yearsYou probably don't need a vector of pointers (use
vector<MyClass>
instead), just be careful since it's a lot more to copy (pass it by reference togetListOfObjects
rather than returning it, which is probably a good idea in either case). -
juanchopanza over 11 years@Dukeling return by value is fine, the copy would get optimised out by named return value optimisation (NRVO). And the code would be cleaner and safer.
-
billz over 11 years@Dr.Kameleon after the function is called, you are copying pointers to other vector, if you iterate through it and delete again, which is UB.
-
Dr.Kameleon over 11 years@billz The initial post has been re-edited to also show how the function is called and how I'm attempting to delete the objects
-
Dr.Kameleon over 11 yearsHmmm... I see your point. Perhaps, you're right. Give me a sec to test it out.
-
johnbakers over 11 yearsI assume that you could tell they were dynamically allocated because the class members would be pointers instead, correct?
-
Karthik T over 11 years@SebbyJohanns Yes thats what I was using.. let me add the caveat
-
Najzero over 11 yearsthis + since boost is already used... maybe using boost.org/doc/libs/1_52_0/libs/smart_ptr/smart_ptr.htm
-
juanchopanza over 11 years@SebbyJohanns Pointer data members does not imply dynamic allocation. You have to check whether these pointers are made to point to some memory dynamically allocated with
new
ornew[]
. Even then it isn't 100% clear who's responsibility it is to call delete. Best to avoid raw pointers in these cases and use the appropriate smart pointer. -
Karthik T over 11 years@juanchopanza Another check would be that this class would have to own it, so ideally, this class would need to have allocated it.
-
Tony Delroy over 11 years"What I see is all allocated on stack" - not true... the members will be embedded where the object is created, which could be static, on the stack or on the heap. The crucial point is that whatever memory management is applied to the object will automatically handle the members... that's where you correctly warn against
new Myclass
sans release. -
Dr.Kameleon over 11 yearsOK, I've been trying to see what's going on with the whole thing and this the case : actually, the
MyClass
objects are created with anew
, and then put in a vector. Now, whenever I trydelete
ing aMyClass
object, once I'm done with it, I'm getting amalloc: *** error for object 0xSOME_MEMORY_ADDRESS: pointer being freed was not allocated
. Any ideas? -
juanchopanza over 11 years@KarthikT Right, but it isn't something you can check easily from looking at a data member declaration. You need to know it (which you should, if you desinged the class), or have the documentation from the class, or make an educated guess from looking at the code.
-
Karthik T over 11 years@Dr.Kameleon you might want to edit the question to show the code where you allocate and deallocate the objects and the definition of the vector, and add these details there
-
Karthik T over 11 years@juanchopanza having no pointers is good enough to infer that the destructor is free though.