false memory leak?

B

benoit808

I don't have a lot of experience with C++ so I apologize if this is a
stupid question.
I use Paul Nettle's memory manager (mmgr.cpp) which reports a memory
leak but I don't think there's one. Here is the code (i took some stuff
out to simplify):

void myFunction()
{
Sprite *pImage;
sprintf(pStr, "s04-%02d.png", i);
pData = pFile->FindFile(pStr, &iSize);
pImage = new Sprite(GetD3DDevice(), pData, iSize, 330, 50);
pImage->DefineFrame(0, 0, 330, 25, 0);
pImage->DefineFrame(0, 25, 330, 25, 0);
pImage->SetAnimFrame(0);

Song *pSong = new Song(strdup(pStr), pImage);
}

The leak is reported on "Sprite *pImage". The pImage object passed to
the Song constructor is being released by the Song destructor. My
understanding is that the pImage pointer is released when myFunction()
exits. Since I do not delete the object before the pointer release, I
assume this is the reason why mmgr.cpp reports the leak.

Am I right or am I missing something?

Ben
 
A

Andre Kostur

I don't have a lot of experience with C++ so I apologize if this is a
stupid question.
I use Paul Nettle's memory manager (mmgr.cpp) which reports a memory
leak but I don't think there's one. Here is the code (i took some stuff
out to simplify):

void myFunction()
{
Sprite *pImage;
sprintf(pStr, "s04-%02d.png", i);
pData = pFile->FindFile(pStr, &iSize);
pImage = new Sprite(GetD3DDevice(), pData, iSize, 330, 50);
pImage->DefineFrame(0, 0, 330, 25, 0);
pImage->DefineFrame(0, 25, 330, 25, 0);
pImage->SetAnimFrame(0);

Song *pSong = new Song(strdup(pStr), pImage);
}

The leak is reported on "Sprite *pImage". The pImage object passed to
the Song constructor is being released by the Song destructor. My
understanding is that the pImage pointer is released when myFunction()
exits. Since I do not delete the object before the pointer release, I
assume this is the reason why mmgr.cpp reports the leak.

Am I right or am I missing something?

Why would the memory pointed to by pImage be released by the above code?
I don't see a delete anywhere in there (And I'm assuming the constructor
of Song doesn't delete the pointer it's passed).
 
B

benj

I don't have a lot of experience with C++ so I apologize if this is a
stupid question.
I use Paul Nettle's memory manager (mmgr.cpp) which reports a memory
leak but I don't think there's one. Here is the code (i took some stuff
out to simplify):

void myFunction()
{
Sprite *pImage;
sprintf(pStr, "s04-%02d.png", i);
pData = pFile->FindFile(pStr, &iSize);
pImage = new Sprite(GetD3DDevice(), pData, iSize, 330, 50);
pImage->DefineFrame(0, 0, 330, 25, 0);
pImage->DefineFrame(0, 25, 330, 25, 0);
pImage->SetAnimFrame(0);

Song *pSong = new Song(strdup(pStr), pImage);
}

The leak is reported on "Sprite *pImage". The pImage object passed to
the Song constructor is being released by the Song destructor. My
understanding is that the pImage pointer is released when myFunction()
exits. Since I do not delete the object before the pointer release, I
assume this is the reason why mmgr.cpp reports the leak.

Am I right or am I missing something?

Ben

put

delete pImage;

after Song *pSong = new Song(strdup(pStr), pImage);
 
B

benoit808

I am aware that the memory pointed by pImage is not released in this
code. What I meant was that the pointer itself is destroyed.
The memory is now being pointed to by the newly created Song object.
The destructor for the Song object does release the memory.
 
B

benoit808

benj,

isn't that going to destroy the object pointed by pImage making it
unavailable to my Song object?
 
G

Gavin Deane

I don't have a lot of experience with C++

In that case, you should probably steer clear of manual memory
management until you have more experience. Then you will know that you
should usually steer clear of manual memory management.
so I apologize if this is a
stupid question.
I use Paul Nettle's memory manager (mmgr.cpp) which reports a memory
leak but I don't think there's one. Here is the code (i took some stuff
out to simplify):

void myFunction()
{
Sprite *pImage;
sprintf(pStr, "s04-%02d.png", i);
pData = pFile->FindFile(pStr, &iSize);
pImage = new Sprite(GetD3DDevice(), pData, iSize, 330, 50);
pImage->DefineFrame(0, 0, 330, 25, 0);
pImage->DefineFrame(0, 25, 330, 25, 0);
pImage->SetAnimFrame(0);

Song *pSong = new Song(strdup(pStr), pImage);
}

The leak is reported on "Sprite *pImage". The pImage object passed to
the Song constructor is being released by the Song destructor.

Every new must be matched by exactly one delete (and every new [] must
be matched by one delete []). Your code has two occurances of new and
no occurances of delete. *IF* the Song destructor deletes the pointer
passed to it, *AND* the Song class handles holding the pointer and the
Rule of Three correctly, *AND* none of the code between allocating the
new Sprite to pImage and passing pImage to the Song constructor can
ever throw an exception, *AND* you don't do anything else with the
pImage pointer that contradicts this ownership policy, *THEN* the
memory allocated to pImage should be OK. Except that the Song object is
dynamically allocated too - is there a reason you couldn't do Song
song(strdup(pStr), pImage);? So you need to be absolutely sure you get
all those things right for pSong as well.
My
understanding is that the pImage pointer is released when myFunction()
exits.

pImage is local to myFunction. At the end of that function, the local
pointer object pImage is destroyed. That is not the same thing as
delete pImage; The memory pointed to by pImage is not deleted
automatically at the end of myFunction.
Since I do not delete the object before the pointer release, I
assume this is the reason why mmgr.cpp reports the leak.

You would have to consult the documentation of your memory manager tool
to understand what forms of code might trigger false alarms.
Am I right or am I missing something?

You are missing the fact that new should never appear out on its own in
your code. You should be using object designed for safely handling
memory (containers and smart pointers - the standard library and boost
have plenty). Doing your own memory management is hard. Where are you
learning C++ from that doesn't tell you this?

Gavin Deane
 
B

benoit808

Man I love those forums, I feel like I'm back in school getting
scolding from my teachers :p

Anyway, Gavin, I would love to stay away from manual memory management.
In this example where I have to create an object, change some of its
attributes and pass it to another constructor, how would you rewrite it
so I don't have to deal with those manual memory management issues?

Thanks for your help

I don't have a lot of experience with C++In that case, you should probably steer clear of manual memory
management until you have more experience. Then you will know that you
should usually steer clear of manual memory management.


so I apologize if this is a
stupid question.
I use Paul Nettle's memory manager (mmgr.cpp) which reports a memory
leak but I don't think there's one. Here is the code (i took some stuff
out to simplify):
void myFunction()
{
Sprite *pImage;
sprintf(pStr, "s04-%02d.png", i);
pData = pFile->FindFile(pStr, &iSize);
pImage = new Sprite(GetD3DDevice(), pData, iSize, 330, 50);
pImage->DefineFrame(0, 0, 330, 25, 0);
pImage->DefineFrame(0, 25, 330, 25, 0);
pImage->SetAnimFrame(0);
Song *pSong = new Song(strdup(pStr), pImage);
}
The leak is reported on "Sprite *pImage". The pImage object passed to
the Song constructor is being released by the Song destructor.Every new must be matched by exactly one delete (and every new [] must
be matched by one delete []). Your code has two occurances of new and
no occurances of delete. *IF* the Song destructor deletes the pointer
passed to it, *AND* the Song class handles holding the pointer and the
Rule of Three correctly, *AND* none of the code between allocating the
new Sprite to pImage and passing pImage to the Song constructor can
ever throw an exception, *AND* you don't do anything else with the
pImage pointer that contradicts this ownership policy, *THEN* the
memory allocated to pImage should be OK. Except that the Song object is
dynamically allocated too - is there a reason you couldn't do Song
song(strdup(pStr), pImage);? So you need to be absolutely sure you get
all those things right for pSong as well.
My
understanding is that the pImage pointer is released when myFunction()
exits.pImage is local to myFunction. At the end of that function, the local
pointer object pImage is destroyed. That is not the same thing as
delete pImage; The memory pointed to by pImage is not deleted
automatically at the end of myFunction.
Since I do not delete the object before the pointer release, I
assume this is the reason why mmgr.cpp reports the leak.You would have to consult the documentation of your memory manager tool
to understand what forms of code might trigger false alarms.
Am I right or am I missing something?You are missing the fact that new should never appear out on its own in
your code. You should be using object designed for safely handling
memory (containers and smart pointers - the standard library and boost
have plenty). Doing your own memory management is hard. Where are you
learning C++ from that doesn't tell you this?

Gavin Deane
 
G

Gianni Mariani

I don't have a lot of experience with C++ so I apologize if this is a
stupid question.
I use Paul Nettle's memory manager (mmgr.cpp) which reports a memory
leak but I don't think there's one. Here is the code (i took some stuff
out to simplify):

void myFunction()
{
Sprite *pImage;
sprintf(pStr, "s04-%02d.png", i);
pData = pFile->FindFile(pStr, &iSize);
pImage = new Sprite(GetD3DDevice(), pData, iSize, 330, 50);
pImage->DefineFrame(0, 0, 330, 25, 0);
pImage->DefineFrame(0, 25, 330, 25, 0);
pImage->SetAnimFrame(0);

Song *pSong = new Song(strdup(pStr), pImage);
}

The leak is reported on "Sprite *pImage". The pImage object passed to
the Song constructor is being released by the Song destructor. My
understanding is that the pImage pointer is released when myFunction()
exits. Since I do not delete the object before the pointer release, I
assume this is the reason why mmgr.cpp reports the leak.

Am I right or am I missing something?

If what you say (that the Song destructor is called and in turn calls
the Sprite destructor), you're right, there is no leak.
 
G

Gavin Deane

Please don't top-post. Thanks. Rearranged.
Man I love those forums, I feel like I'm back in school getting
scolding from my teachers :p

Anyway, Gavin, I would love to stay away from manual memory management.
In this example where I have to create an object, change some of its
attributes and pass it to another constructor, how would you rewrite it
so I don't have to deal with those manual memory management issues?

Well, without knowing any more of your requirements, or anything about
the classes involved, the obvious answer is to have a Song object own
its Sprite object.

Sprite image(GetD3DDevice(), pData, iSize, 330, 50);
image.DefineFrame(0, 0, 330, 25, 0);
image.DefineFrame(0, 25, 330, 25, 0);
image.SetAnimFrame(0);
Song song(strdup(pStr), image);

That does involve copying the Sprite object, which, based on its name,
I can imagine might be expensive. If so, and if, as your original code
suggests, the Sprite is owned by and exists only in the Song, then the
Song perhaps needs a constructor and/or member functions that allow you
to manipulate the Sprite as required via the Song interface. But as I
say, without knowing more about what you're trying to do, I'm
speculating and I could be spot on or I could be a million miles away.

Gavin Deane
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

can't convert from type A* to type B* 14
Memory Leak 5
memory leak problem 0
memory leak 4
memory leak problem 2
Memory Leak detection 1
Memory leak problem? 4
Number of objects grows unbouned...Memory leak 1

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top