"Detected memory leaks" when using class "MemoryBlock"

Hello, everyone! I just started learning JUCE, in my project, I used “MemoryBlock” class by this way:

[code]class alignedMemoryBlock: public juce:: MemoryBlock
{
public:
OneBuffer (int L);
~ OneBuffer ();
void * alignP;
};

[/code]

and in the constructor:

[code]alignedMemoryBlock:: alignedMemoryBlock (int L): MemoryBlock (L +16, false)
{
int K = 0;
K = (int) getData ();
if (K == 0) {
BufferWrong ();
AignedP = 0;
return;
}
if (K% 16! = 0) {
K = K + (16-K% 16);
}
AignedP = (void *) (K);
}

[/code]

So I can get 16-byte aligned MemoryBlock.

Then I created a class:

[code]class FreqMath: FreqDel, FreqBase
{
private:
alignedMemoryBlock * REDE, * ER, * EI, * ERREV, * EIREV, * WEIGHTA, * XFADER, * BITREVNUMBERDEL, * BITREVNUMBERDEL2;



};

FreqMath:: FreqMath (int k, int D, int C): FreqBase (k), FreqDel (D)
{




REDE = new OneBuffer (LengthMax * 8,8);
EI = new OneBuffer (L * 8,8);
ER = new OneBuffer (L * 8,8);
EIREV = new OneBuffer (L * 8,8);
ERREV = new OneBuffer (L * 8,8);
XFADER = new OneBuffer (C * 8,8);
WEIGHTA = new OneBuffer ((LengthMax / 2 +1) * 8,8);
BITREVNUMBERDEL = new OneBuffer (Del * sizeof (int), 0);
BITREVNUMBERDEL2 = new OneBuffer (Del * 2 * sizeof (int), 0);
}

FreqMath:: ~ FreqMath ()
{
REDE-> ~ OneBuffer ();
ER-> ~ OneBuffer ();
EI-> ~ OneBuffer ();
ERREV-> ~ OneBuffer ();
EIREV-> ~ OneBuffer ();
WEIGHTA-> ~ OneBuffer ();
XFADER-> ~ OneBuffer ();
BITREVNUMBERDEL-> ~ OneBuffer ();
BITREVNUMBERDEL2-> ~ OneBuffer ();
}

[/code]

Finally, in the main function:

[code]# Include

Include “FreqMath.h”

int main () {
FreqMath A (4,2,8);
system (“pause”);
return 0;
}
[/code]

I think that’s good !
So I press F5, VC2011 told me:

Detected memory leaks!
Dumping objects ->
{281} normal block at 0x023B5CF8, 20 bytes long.
Data: <H]; > 48 5D 3B 02 CD CD CD CD 20 00 00 00 CD CD CD CD
{279} normal block at 0x023B5C58, 20 bytes long.
Data: < ; > A8 5C 3B 02 CD CD CD CD 10 00 00 00 CD CD CD CD
{277} normal block at 0x023B5B80, 20 bytes long.
Data: < [; H > D0 5B 3B 02 CD CD CD CD 48 00 00 00 CD CD CD CD
{275} normal block at 0x023B5AB0, 20 bytes long.
Data: < [; @ > 00 5B 3B 02 CD CD CD CD 40 00 00 00 CD CD CD CD
{273} normal block at 0x023B5A00, 20 bytes long.
Data: <PZ; > 50 5A 3B 02 CD CD CD CD 20 00 00 00 CD CD CD CD
{271} normal block at 0x023B5950, 20 bytes long.
Data: < Y; > A0 59 3B 02 CD CD CD CD 20 00 00 00 CD CD CD CD
{269} normal block at 0x023B4070, 20 bytes long.
Data: < X; > F0 58 3B 02 CD CD CD CD 20 00 00 00 CD CD CD CD
{267} normal block at 0x023B3FC0, 20 bytes long.
Data: < @; > 10 40 3B 02 CD CD CD CD 20 00 00 00 CD CD CD CD
{265} normal block at 0x023B3EB0, 20 bytes long.
Data: < ?; > 00 3F 3B 02 CD CD CD CD 80 00 00 00 CD CD CD CD
Object dump complete.

why? where I did wrong?THX!

Wow. Does any of that really compile??

To explain all the mistakes in this code would take a very long time, I’m afraid. But your main question, “why is it leaking” is because of this:

FreqMath:: ~ FreqMath () { REDE-> ~ OneBuffer (); ER-> ~ OneBuffer (); EI-> ~ OneBuffer (); ERREV-> ~ OneBuffer (); EIREV-> ~ OneBuffer (); WEIGHTA-> ~ OneBuffer (); XFADER-> ~ OneBuffer (); BITREVNUMBERDEL-> ~ OneBuffer (); BITREVNUMBERDEL2-> ~ OneBuffer (); }

…which I can only describe as “WTF?” Where on earth did you pick up nonsense like that!?! Go and learn about how new/delete works in C++!

And then, when you do understand how new/delete works, stop using it! Always use object composition where possible, not pointers. And never inherit from a class like MemoryBlock, or anything that doesn’t have a virtual destructor. (The compiler must have warned you about that - don’t ignore it!). In general, you should never inherit at all if you can achieve the same result using object composition - there are lots of good c++ tutorials out there that give really good explanations of when you should use inheritance vs composition.

While reading your code, I’ve been wondering several times in which language it was written :wink:

On a more serious note : under Visual C++, the memory leak checker isn’t usefull at all. Try the (free) VLD add on which displays the call stack of the allocation causing the leak.

Looking at that code was a fun puzzle.

Anyway, Jules, the need for aligned data is real though. What about adding to MemoryBlock to support alignment?

I was wondering ‘what he/she should have done’ - apart from learning C++, obviously, and the best in the new scheme would presumably be a set of ScopedPointer for the buffers - we’ll assume they’re actually needed, but if you don’t advocate sub-classing MemoryBlock, then getting an aligned data pointer out of it would be clunky, right (without doing the math every time you need it, or risking keeping a raw pointer around)?

Bruce

Just a helpful pointer, since we all piled on:

Something like:

class FreqMath: FreqDel, FreqBase { private: ScopedPointer <MemoryBlock> REDE, ER, EI, ERREV, EIREV, WEIGHTA, XFADER, BITREVNUMBERDEL, BITREVNUMBERDEL2; .................. ................. ............... };

Means that all your buffers will be automagically cleaned up for you when your FreqMath instance is deleted. Absent Jules’ tips earlier, I would personally have considered a MemoryBlock subclass, just overriding a constructor to add 16 bytes to each assignment, and adding a getAlignedData to pass back an aligned pointer to the data in the correct pointer type - not adding any members, since getting them deleted wouldn’t work.

But I read a lot of C++ books - still no expert, but I put the work in. It’s not a picnic, even with Juce. Check out the Wiki pages - I believe there’s tips about new pointer types.

Bruce

Well…thank u all ! I think I understand where I did wrong…

Does this mean that when I do “~alignedMemoryBlock()” , in fact, it runs the MemoryBlock s destructor?
So somthing in “alignedMemoryBlock” has not been released form heap?

Is that right?

And…Im Sorry,I asked a Stupid question…
I started Learning C++ only a few months.

You never call ~Anything.

As Jules said, the C++ new and delete keywords apply, you never explicitly call a destructor. You better look them up and get your head around it - if you just ‘solve’ your current problem, you will run into trouble later.

Bruce

The best approach could be as simple as this:

[code]class AlignedMemoryBlock
{
public:
AignedMemoryBlock (int size) : block (size + 16) {}

void* getData() const    { return (void*) (((pointer_sized_int) block.getData() + 15) & ~15); }

private:
MemoryBlock block;
};[/code]

And you definitely shouldn’t use ‘new’ for objects like this, not even with a ScopedPointer - just embed the objects directly into their parent object and there’s no need to worry about creating or destroying them, e.g.

class FreqMath: FreqDel, FreqBase { private: AlignedMemoryBlock REDE, ER, EI, ERREV, EIREV, WEIGHTA, XFADER, BITREVNUMBERDEL, BITREVNUMBERDEL2; .................. ................. ............... };

And for god’s sake sort out that awful spacing and capitalisation!!

Well…Thanks Everyone.
Today I have changed my code and it seems a lot better
And I copied the code … thank you jules
I will never use the "new / delete"like this, forever…

And…As Bruce said ,I think there are many people who need aligned data ,
for SSE things or something else.