• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Vanz

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 this post


Link to post
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];

}

 

instead do this:

 

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 sad.png

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 this post


Link to post
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 this post


Link to post
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 sad.png

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0