Memory Leak

K

KS

Hello,

I have a memory leak in my application and I have identified two lines
of code that cause the leak. If I comment out these lines, the program
runs fine. If left uncommented, the memory usages keeps increasing till
the program terminates due to lack of available memory.

I have marked the two lines that cause this problem in the code in the
function main() (at the bottom of the file).

Code: http://www.grex.org/~kpp/cmultiknapsack.cpp
Required File in the same directory:
http://www.grex.org/~kpp/orlib1.txt

Can you identify the problem? (I know the code needs a lot of work but
first I must fix this leak)

KS
 
B

Bo Persson

KS said:
Hello,

I have a memory leak in my application and I have identified two
lines
of code that cause the leak. If I comment out these lines, the
program
runs fine. If left uncommented, the memory usages keeps increasing
till
the program terminates due to lack of available memory.

I have marked the two lines that cause this problem in the code in
the
function main() (at the bottom of the file).

Code: http://www.grex.org/~kpp/cmultiknapsack.cpp
Required File in the same directory:
http://www.grex.org/~kpp/orlib1.txt

Can you identify the problem? (I know the code needs a lot of work
but
first I must fix this leak)

I can find "new vector<KNode>" in the code, but no "delete vector".
Why?


Passing around pointers *is* dangerous.


Bo Persson
 
K

KS

I can find "new vector<KNode>" in the code, but no "delete vector".
Why?


Passing around pointers *is* dangerous.

Thanks for the reply. I added delete, but that does not change
anything. (Actually I had non-pointer vectors but I changed them to
pointers to debug this memory leak).
 
J

Jens Theisen

KS said:
Can you identify the problem? (I know the code needs a lot of work but
first I must fix this leak)

One leak is obviously in the main loop, since the returned vectors are
not freed. You need to replace the two lines

children->erase(children->begin(), children->end());
parents->erase(parents->begin(), parents->end());

with

delete children;
delete parents;

It might be that this is enough, though it's a bit hard to tell; there
could as well be more leaks.

I strongly recommend the use of smart pointers. It's not much effort to
replace all your c-style pointers with std::auto_ptr or
boost::shared_ptr, and you will detect all leaks unless you have cyclic
dependencies, which I don't think you have.

Jens
 
L

Lars Uffmann

KS said:
Can you identify the problem? (I know the code needs a lot of work but
first I must fix this leak)

In your function greedyCrossover(..) (called by crossover(..), called in
the main loop), you reserve memory in the line

int * kk = new int[NUMBER_OBJECTS];

for use in a call to the KNode constructor
KNode(int * knap) {...}

However, in the KNode constructor, the values of
that integer-array are duplicated to newly reserved
memory and the array "kk" created by greedyCrossover
is never freed. This _will_ create a memory leak of
increasing size, and depending on how often the function
is called, it might end up cluttering all your remaining
memory.

Best Regards,

Lars
 
L

Lars Uffmann

Oh btw since I am currently working on debugging a TON of memory
leaks in someone elses (huge) code files, here's a tip:

I am not sure under which operating system you work, but try
using the gnu-compiler and use the mtrace() function :)

Call that as a first thing in your main loop (#include <mcheck.h>)
and then if you start your program with the environment variable
MALLOC_TRACE=filename, the function mtrace() will make
sure that ALL memory allocations and freeing of memory will
be logged into that file, which later a perl script called mtrace
will evaluate. I don't know where to get that script for windows
but I am sure you'll find something on google.

Then, in your program, just enter an exit(0); after the line you suspect
causing the memory leak and in the function called there, you add
a return-statement before any other code is called.
Then run the program and make sure you have no memory
leaks so far.
If that is confirmed, move the return-statement in the function down,
line by line (or in larger steps if you wish) until the memory leak
occurs. Don't forget to free all reserved memory that you have
_above_ the return statement BEFORE exiting the function :)

Same for the main functions exit-call - free all memory that you
would normally free at the end of the function before calling exit();

That strategy works awesome for me :)

Best Regards,


Lars
 
G

Greg Comeau

Oh btw since I am currently working on debugging a TON of memory
leaks in someone elses (huge) code files, here's a tip:

I am not sure under which operating system you work, but try
using the gnu-compiler and use the mtrace() function :)

Call that as a first thing in your main loop (#include <mcheck.h>)
and then if you start your program with the environment variable
MALLOC_TRACE=filename, the function mtrace() will make
sure that ALL memory allocations and freeing of memory will
be logged into that file, which later a perl script called mtrace
will evaluate. I don't know where to get that script for windows
but I am sure you'll find something on google.

Then, in your program, just enter an exit(0); after the line you suspect
causing the memory leak and in the function called there, you add
a return-statement before any other code is called.
Then run the program and make sure you have no memory
leaks so far.
If that is confirmed, move the return-statement in the function down,
line by line (or in larger steps if you wish) until the memory leak
occurs. Don't forget to free all reserved memory that you have
_above_ the return statement BEFORE exiting the function :)

Same for the main functions exit-call - free all memory that you
would normally free at the end of the function before calling exit();

That strategy works awesome for me :)

Brute force such as this is sometimes necessary.
I just wanted to point out that this technique is not failsafe.
For instance, it may not help with some threaded stuff,
or just a good old fashioned mischevious bug.
 
K

KS

In your function greedyCrossover(..) (called by crossover(..), called in
the main loop), you reserve memory in the line

int * kk = new int[NUMBER_OBJECTS];

for use in a call to the KNode constructor
KNode(int * knap) {...}

However, in the KNode constructor, the values of
that integer-array are duplicated to newly reserved
memory and the array "kk" created by greedyCrossover
is never freed. This _will_ create a memory leak of
increasing size, and depending on how often the function
is called, it might end up cluttering all your remaining
memory.

Best Regards,

Lars

Yes, thats where the leak was. Thanks, Lars, for your help.
 
L

Lars Uffmann

Greg Comeau said:
Brute force such as this is sometimes necessary.
I just wanted to point out that this technique is not failsafe.
For instance, it may not help with some threaded stuff,
or just a good old fashioned mischevious bug.

Can you be more precise, especially specifying what
mischevious bug you mean?
I am aware that this won't find simple bugs, I use this simply
on the hunt for _memory_ leaks - nothing else :)

I know it won't make some code bug-free, one thing that
happened a lot in this project I am working on is that pointers
would be freed in the destructor of an object a) without
setting them to 0 in the constructor and b) without checking
IF they were set to anything else than 0 before deletion.

delete (void *) 0;
is bound to produce something funny (well - a segmentation
fault...)

Now if those pointers are only set to allocated memory
upon meeting some conditions during runtime, there might
not occur a memory leak while the danger is still there.

Yes, I am aware of that - did you mean anything else I should
watch out for when debugging projects messed up by other
people? :)

Best Regards,

Lars
 
L

Lars Uffmann

KS said:
Yes, thats where the leak was. Thanks, Lars, for your help.

Welcome, glad to be able to return something to the group
after receiving some very valuable tips :)


Regards,

Lars
 
B

Bernd Strieder

Hello,

Lars said:
Oh btw since I am currently working on debugging a TON of memory
leaks in someone elses (huge) code files, here's a tip:

I am not sure under which operating system you work, but try
using the gnu-compiler and use the mtrace() function :)

Check valgrind, whether it is available for the platform in question.

http://www.valgrind.org

It catches even more kinds of problems, and can tell you the source
lines, where leaked allocations, or uninitialized accesses happen. This
makes eliminiating leaks really one of the easier problems.

Bernd Strieder
 
G

Greg Comeau

Can you be more precise, especially specifying what
mischevious bug you mean?
I am aware that this won't find simple bugs, I use this simply
on the hunt for _memory_ leaks - nothing else :)

I know it won't make some code bug-free, one thing that
happened a lot in this project I am working on is that pointers
would be freed in the destructor of an object a) without
setting them to 0 in the constructor and b) without checking
IF they were set to anything else than 0 before deletion.

delete (void *) 0;
is bound to produce something funny (well - a segmentation
fault...)

Now if those pointers are only set to allocated memory
upon meeting some conditions during runtime, there might
not occur a memory leak while the danger is still there.

Yes, I am aware of that - did you mean anything else I should
watch out for when debugging projects messed up by other
people? :)

I didn't have anything specific in mind, just that often
folks use a certain technique or tools as a foolproof
tactic and usually it is not exactly that. So I'm always
cautious of false sense of security.

BTW delete of a null pointer is well defined.
 
L

Lars Uffmann

Greg Comeau said:
I didn't have anything specific in mind, just that often
folks use a certain technique or tools as a foolproof
tactic and usually it is not exactly that. So I'm always
cautious of false sense of security.

Oh :) Don't worry, I was just using the described technique
along with a bunch of other things to find all memory leaks
that actually HAPPENED in one specific run of the program :)

I know that I might miss errors popping up with different
config files and the likes...
BTW delete of a null pointer is well defined.

Oh is it? Segmentation Fault? :)


Regards,

Lars
 
K

Kai-Uwe Bux

Lars said:
Oh :) Don't worry, I was just using the described technique
along with a bunch of other things to find all memory leaks
that actually HAPPENED in one specific run of the program :)

I know that I might miss errors popping up with different
config files and the likes...


Oh is it?
Yes.

Segmentation Fault? :)

No: null op.


Best

Kai-Uwe Bux
 
G

Greg Comeau

Oh is it? Segmentation Fault? :)

No, that is not an allowed behavior, instead it is
that that there is no effect, upon the observable
behavior. IOWs a no-op.

I would still avoid it when possible though; that is,
not go out of my way to call it.
 

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


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top