We help IT Professionals succeed at work.

C++ Programming question  ( simple? )

tullhead
tullhead asked
on
168 Views
Last Modified: 2017-04-11
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
{
public:
      DECLARE_SERIAL(Chunk);
      void Serialize(CArchive& ar);

      Chunk()
      {
            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;
Comment
Watch Question

CERTIFIED EXPERT
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Author

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....
CERTIFIED EXPERT

Commented:
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?
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

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.

Author

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()

Author

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)
CERTIFIED EXPERT

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)
CERTIFIED EXPERT

Commented:
Incidentally, you can (and should) avoid memory leaks by using smart-pointers.
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

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)
CERTIFIED EXPERT

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?

Author

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)
CERTIFIED EXPERT

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.

Author

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)
CERTIFIED EXPERT

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).

Author

Commented:
OK. Thanks a million for your help.  I will try now...
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
No worries.
CERTIFIED EXPERT

Commented:
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 ;) .

Author

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)
CERTIFIED EXPERT

Commented:
You're very welcome.
CERTIFIED EXPERT

Commented:
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.
CERTIFIED EXPERT
Top Expert 2016

Commented:
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.

ChunkArray.clear(); 

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


Sara
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
Of course, you can achieve the same using unique_ptr.

Author

Commented:
Thanks!

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions