Followers 0

# Memory Leaks

## 11 posts in this topic

I always strive to write my programs so they are Rock Solid, please share what techniques and/or programs you use to hunt down those nasty memory leaks. Some common ones I run into

[Source]
int i, a[10];

for(i=0;i<15;i++)
a[i]=i;
[/Source]

One technique I use to track them down or errors in general is I write a for loop to a high number say 100,000 then I keep calling that function. If it has a memory leak it will usually crash or I examine Task Manager-> Performance and watch the Free Memory shrink.

Another one, that I think causes a crash:

[Source]

BitBlt(hdc, -5, -5 , 100 , 100, hdcPic, 0, 0, SRCCOPY);
[/Source]

When using GDI, does blitting outside the screen resolution cause a memory leak?

Any other common ones you can think of? An example is always helpful... how do you find em?

Thanks for sharing...

Vanz

0

##### Share on other sites

Well, I always make sure my dynamic arrays are deleted before allocating more memory, and I also make sure I allocate enough memory before accessing it.

Don't do this:

int * i = new int[10];

somefunc(){

i = new int[11];

}

int * i = new int[10];

somefunc(){

delete[]i;

i = new int[11];

}

Do not do this:

int * i = new int[10];

somefunc{

int var = i[11];

}

Make sure you allocated enough memory in your dynamic array.

Also, make sure you only call delete once, or if there is a possible instance of you calling delete twice, set the variable to NULL when you delete it. Deleting a NULL pointer has no effect.

Edited by ProvenDantheman
0

##### Share on other sites

rhuala, on 12 Feb 2013 - 18:49, said:

int i, a[10];
for(i=0;i&lt;15;i++)
a[i]=i;

That's not a memory leak. That's a buffer overrun. You can avoid it by not using magic numbers:
const size_t ARRAY_LENGTH = 10; //or whatever
int ary[ARRAY_LENGTH];
for(int i=0; i &lt; ARRAY_LENGTH; ++i) {
ary[i] = i;
}

Quote
One technique I use to track them down or errors in general is I write a for loop to a high number say 100,000 then I keep calling that function. If it has a memory leak it will usually crash or I examine Task Manager-&gt; Performance and watch the Free Memory shrink.

No bueno. This will only catch leaks that always happen, and it's too hard to distinguish from normal allocation behavior if leaks are small. Use a utility like VLD instead, and use smart pointers and RAII to make leakage a non-issue.

Quote
Another one, that I think causes a crash:

BitBlt(hdc, -5, -5 , 100 , 100, hdcPic, 0, 0, SRCCOPY);
When using GDI, does blitting outside the screen resolution cause a memory leak?

No. It clips the blit according to the target context.

You're confused about what a memory leak is, or at least about what causes them.

This is a memory leak:
int main() {
int* derp = new int;
return 0;
}

This is a harmless one, but it's a leak because memory is allocated and not freed. You avoid memory leaks by strictly following proper memory management practices like RAII.

The examples you gave were concerning buffer overrun behavior. You avoid overruns by limiting buffer actions by always implementing bounds checking. Write loops in such a way that they are made aware of - and are unable to pass beyond - the end of the buffer, etc. Use the secure CRT functions rather than the original ones.

ProvenDantheman, on 12 Feb 2013 - 18:59, said:
Also, make sure you only call delete once, or if there is a possible instance of you calling delete twice, set the variable to NULL when you delete it. Deleting a NULL pointer has no effect.

Obscuring a bug is not the same as fixing a bug. Your program should always be aware of its allocations and react intelligently. NULL deletion has its uses but abusing it to avoid implementing allocation control is like taking aspirin instead of going to the hospital after cutting your arm off. Edited by Khatharr
2

##### Share on other sites

I avoid dynamic memory except where performance is really needed, preferring the priority of: local or member variables -> smart pointers -> manual dynamic memory
I use std::vectors even when I need a static size (I'll switch to C++11's std::array for static sizes soon - last I checked that wasn't implemented in my compiler, but that was quite a while ago).
Other than that, I also avoid funky pointer manipulation, and in general prefer references where suitable.

(The latter two helping with memory corruption rather than memory leaks - something that I dread trying to debug)

Edited by Servant of the Lord
0

##### Share on other sites

rhuala, on 12 Feb 2013 - 18:49, said:

int i, a[10];
for(i=0;i&lt;15;i++)
a[i]=i;

That's not a memory leak. That's a buffer overrun. You can avoid it by not using magic numbers:
const size_t ARRAY_LENGTH = 10; //or whatever
int ary[ARRAY_LENGTH];
for(int i=0; i < ARRAY_LENGTH; ++i) {
ary[i] = i;
}

QFT - the OP's examples are all about memory corruption, not memory leaks at all

Another technique that you can use for arrays (but not arrays that have been cast/decayed into pointers) is:
template <typename T, int N> uint ArraySize(T(&)[N]) { return N; }
...
for(int i=0; i < ArraySize(ary); ++i) {
ary[i] = i;
}
0

##### Share on other sites

It may be not as efficient, but I tend to use STL everywhere (until I need to optimize).  It's much easier to maintain/read.

const int NUM_THINGS = 10;

std::vector<int> myThings(NUM_THINGS);

for( const auto& thing : myThings ){
do_something_with(thing);
}

It also makes it quite difficult to accidentally overrun your buffer.

Edited by Polarist
1

##### Share on other sites

rhuala, on 12 Feb 2013 - 18:49, said:



int i, a[10];
for(i=0;i&lt;15;i++)
a[i]=i;

That's not a memory leak. That's a buffer overrun. You can avoid it by not using magic numbers:


const size_t ARRAY_LENGTH = 10; //or whatever
int ary[ARRAY_LENGTH];
for(int i=0; i < ARRAY_LENGTH; ++i) {
ary[i] = i;
}

QFT - the OP's examples are all about memory corruption, not memory leaks at all

Another technique that you can use for arrays (but not arrays that have been cast/decayed into pointers) is:


template <typename T, int N> uint ArraySize(T(&)[N]) { return N; }
...
for(int i=0; i < ArraySize(ary); ++i) {
ary[i] = i;
}

okay my bad, I apologize... whatever it's called it leads to crashes or flaky behavior, I guess my technique sucks... although I never do allocate an array with a number, it's always a #define or const

Edited by rhuala
0

##### Share on other sites

I just replace operator new and delete (and malloc and free) with my own memory manager. You can then inject data blocks at the front and back of the allocated memory and place a defined data block there. You can detect buffer overruns by validating they are unchanged (the typical term for this is 'sentinels'). You can also detect memory leaks easily, most of that functionality is removed in release or master builds for performance reasons, and it can becoime a fairly large module in itself depending how much functionality you want but it's the best way to track downn these issues that can occur in all levels of C++ programming.

n!

Edited by nfactorial
0

##### Share on other sites

rhuala, on 12 Feb 2013 - 23:24, said:
okay my bad, I apologize... whatever it's called it leads to crashes or flaky behavior, I guess my technique sucks... although I never do allocate an array with a number, it's always a #define or const

Not yelling at you. Just clarifying the difference between the concepts.
0

##### Share on other sites

please share what techniques and/or programs you use to hunt down those nasty memory leaks.

During development I try to use good coding practices like RAII when appropriate and not separating allocation/deallocation responsibility.

Then when there's time for a release I do a profiling session using the Instruments app that comes with Xcode. It's very good for tracking memory allocation and leaks, but sometimes I also turn on memory scribble and guards to do even more thorough testing.

0

##### Share on other sites

I typically just run valgrind on my program, it catches basically everything. Sometimes it's helpful enough to tell me exactly what is leaking, though generally it's easy enough to deduce that from the size of the leaked resource. Though that's under Linux, and I'm not sure if opengl and other large libraries work together well with valgrind, but never had a problem so far.

I usually don't worry too much about memory leaks anyway. If your program is leaking memory, you may just have forgot something somewhere and that's easy to fix. If your design is so bad that it is otherwise incapable of correctly freeing its memory, you have big architectural problems. So usually, I just run valgrind from time to time, to pick up any accidental leaks I might have missed, and I'm good to go. That's in C, anyway. In C++ it's almost impossible to leak memory with the RAII model.

Edited by Bacterius
2

##### Share on other sites

I just replace operator new and delete (and malloc and free) with my own memory manager. You can then inject data blocks at the front and back of the allocated memory and place a defined data block there. You can detect buffer overruns by validating they are unchanged (the typical term for this is 'sentinels'). You can also detect memory leaks easily, most of that functionality is removed in release or master builds for performance reasons, and it can becoime a fairly large module in itself depending how much functionality you want but it's the best way to track downn these issues that can occur in all levels of C++ programming.

n!

I'm very interested in this approach, could you share any resources that you find particularly useful for implementing this approach?  It seems like a very elegant way to approach this issue, and would be much cleaner syntax than what I'm used to doing (i.e. shenanigans in constructors or a clunky factory approach).

0

## Create an account

Register a new account