C++ Programming question ( simple? )

Found a memory leak when I delete a ChunkArray.   But I'm not sure how to fix it.  How to a deallocate or recover the memory used in "buffer" ?

class Chunk : public CObject
      void Serialize(CArchive& ar);

            used = 0;

      ~Chunk()   // 8.0.24
            // How to clean buffer?  

         BYTE buffer[0x2000];  // 8KB
      int used;             // How many bytes of "buffer" are used

// Define an Array type for Chunk
typedef CArray<Chunk*, Chunk*> ChunkArray;
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Generally, when you want to delete an object from your array, the array object knows how to delete the pointer. However, you have pointers stored in your array (that is addresses of the target objects). It is your responsibility to decide who owns the object (it can be shared via a pointer) and delete the object separately. For your ChunkArray, you have to traverse the array and delete the elements first.

In other words, the RemoveAll would delete the addresses (so, it does its job). However, you need to call explicitly the delete ptr in the loop before calling the RemoveAll.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
tullheadAuthor Commented:
Could you show me how to call "delete ptr" - I guess that's the part I don't know.   Normally I use an MFC collection type and not something like "BYTE buffer[ox2000]" but in this case I need to due to code by others.  So I just don't know how to delete the byte array....
The buffer is wrapped inside the Chunk instance. When you delete the Chunk object, the buffer will be deleted automatically -- unless it contains also pointers to something than must be deleted earlier. Can you show some code that would clarify what you exactly do?
Ensure Business Longevity with As-A-Service

Using the as-a-service approach for your business model allows you to grow your revenue stream with new practice areas, without forcing you to part ways with existing clients just because they don’t fit the mold of your new service offerings.

evilrixSenior Software Engineer (Avast)Commented:
Buffer is just a stack array of bytes. It doesn't need to be deleted. It is an "auto" type variable, meaning it is automatically deleted for you. If you have a memory leak it is not specifically because you are not deleting buffer and, in fact, it would be wrong to do so since it is not allocated on the heap. As pepr said, you need to show/explain more.
tullheadAuthor Commented:
If I have

ChunkArray* pCA;

and later, I just want to delete the whole thing with

delete pCA;

but this burns heap.  I think its because I don't do anything in ~Chunk()
tullheadAuthor Commented:
evilrix -- yes, that's what I had thought when I wrote the code originally.  But somehow, it is burning heap.   Instead of  just doing

delete pCA;

do I have to iterate thru the array and delete each element first?  I had thought not.
evilrixSenior Software Engineer (Avast)Commented:
>>   I think its because I don't do anything in ~Chunk()
You don't need to do anything in ~Chunk(), since you are not allocating any resources in that class that are not automatically being deallocated for you.
evilrixSenior Software Engineer (Avast)Commented:
Incidentally, you can (and should) avoid memory leaks by using smart-pointers.
evilrixSenior Software Engineer (Avast)Commented:
>> do I have to iterate thru the array and delete each element first?  I had thought not.
Unless you are allocating data into the array from the heap, no. Given that buffer is just declared as a stack array of bytes you should not need to do anything to deallocate it. Why do you think it is "burning" heap and why do you believe it's this bit of code rather than something else?
evilrixSenior Software Engineer (Avast)Commented:
>> typedef CArray<Chunk*, Chunk*> ChunkArray;
Just out of interest, how are you allocating/deallocating memory for each Chunk? This is a more likely candidate for the leak. How is each Chuck that makes up ChunkArray being deallocated?
tullheadAuthor Commented:
Each Chunk is created as

Chunk* pC = new Chunk();

and then later I stick it into the array...

pCA->SetAt(I, pC);
evilrixSenior Software Engineer (Avast)Commented:
Okay, and I assume that each item added to the CArray is deallocated using "delete" before you destroy the array? Again, you should consider using a smart pointer. I'd also consider using std::vector as it's part of the C++ standard, whereas CArray isn't (it's part of Microsoft's MFC), but that's just me.
tullheadAuthor Commented:
Right now, I'm simply doing
delete pCA;   // the array
So, you are saying that because I use "new" in creating the elements, I *do* have to iterate thru the array and call delete on each element?
evilrixSenior Software Engineer (Avast)Commented:
Yes, everything you allocation using "new" must be deallocated using new. Sorry, when you referred to the array I thought you meant buffer, which is an actual array. ChunkArray is a CArray (which is a class that represents an array).
tullheadAuthor Commented:
OK. Thanks a million for your help.  I will try now...
evilrixSenior Software Engineer (Avast)Commented:
No worries.
To add, when you have ChunkArray* pCA; and later you delete pCA;, you are leaking not only the dynamically allocated elements of the ChunkArray, but you are also leaking the whole ChunkArray.

It seems you are used to Java or C# or the like language where the pointers are hidden behind the scene and where the garbage collector cleans automatically the "leaked" objects. I am not writing it you did not know, but you may be used to some style of work. In C++, the static creation of an object may be a better alternative to the dynamic (new) creation -- whenever it is possible. From my experience, you should also prefer references to pointers. And if nothing of this is possible, use smart pointers, as evilrix wrote.

I guess, you should continue in discussion to make it clear (for us and for yourself ;) .
tullheadAuthor Commented:
OK, now its fixed: simply needed to iterate thru the array and delete each element before deleting the array.  I do this for dozens of other classes in my project -- my brain just went off track because I jumped to the false conclusion it had something to do with my use of "BYTE buffer[0x2000]" a sort of large allocation that I typically don't do.  But of course, it is simple: things created with "new" should later be recovered with "delete".  So, thanks a lot to both of you for helping and putting up with my dumbness.
evilrixSenior Software Engineer (Avast)Commented:
You're very welcome.
It may be a good idea to create your own class that wraps the ChunkArray and knows how to destroy itself correctly -- especially when you need it on more than one place, or when you find yourself writing some code repeatedly.

The "hybrid" features of C++ (read it "more natural") allow also to write functions or templates to "purge" the object passed as the argument.
as suggested by evilrix you may consider to using std::vector as array container. i would try to store the Chunk elements as objects and not as pointers

#include <vector>

std::vector<Chunk> ChunkArray;

this would store an array of Chunk objects instead of pointers. the Advantage is that the array elements don't need to be deleted.


Open in new window

would release all memory,

to add a new Chunk and get access to the new Chunk added you can do

ChunkArray.resize(ChunkArray.size()+1); // creates a new empty Chunk
Chunk & newChunk = ChunkArray.back();

Open in new window

evilrixSenior Software Engineer (Avast)Commented:
Of course, you can achieve the same using unique_ptr.
tullheadAuthor Commented:
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.