29

Obviously Wikipedia has a fair amount of information on the topic, but I wanted to make sure I understand. And from what I can tell it's important to understand the stack/heap relationship to really understand a memory leak?

So here's what I (think) I understand. Corrections are very welcome!

When you first start your program, a block of memory is allocated, say 0x000 to 0xFFF. The first part (say 0x000 to 0x011) is the code/text segment where the program code is loaded.

+--------------+ 0x011
| Program Code |
+--------------+ 0x000

Then you have the stack (say 0x012 to 0x7ff) that holds local variables, and they are stored/retrieved FIFO. So if you had something like

char middleLetter(string word){
     int len = word.length();
     return word[len/2];
}

int main(){
   int cool_number;
   char letter;
   letter = middleLetter("Words");
   ...

Then your variables would be allocated on the stack, which would look like this:

+-------------+ 0x7ff
|             |
|             |
|             |
| ...         |
| len         |
| letter      |
| cool_number |
+-------------+ 0x012

Of course, if you were allocating memory somewhere (using malloc or new), but never freeing it, then your heap could look like this, and you now have a memory leak:

+-------------+ 0xfff
|             |
| malloc(20)  | 0xf64
| malloc(50)  | 0xf32
| malloc(50)  | 0xf00
| ...         |
|             |
+-------------+ 0x800

What this means is that while you can directly access 0xf32 with pointer arithmetic, the OS/your program thinks that memory locations 0xf00-0xf46 are already taken, and won't ever use those spots for storage again, until your program is closed and the memory is freed. But what about shared memory? Wikipedia says it won't ever be released (until your computer is restarted?). How do you know if it's shared memory?

Is this a pretty good basic understanding? Is there anything I'm missing/have wrong? Thanks for looking!

martineau
  • 119,623
  • 25
  • 170
  • 301
Wayne Werner
  • 49,299
  • 29
  • 200
  • 290

9 Answers9

10

Seems like you do understand it - with one exception: In your example, len is a stack variable like everything else. new or malloc create on the heap, everything else (local variables etc) is on the stack. And main's local variables are not different from any other function's variables.

Shared memory is a rather rare case, you usually don't need it and therefore you won't have it unless you explicitly ask for it (otherwise, some random other process may use the very same memory your process uses - obviously, this would break things badly).

  • That's what I originally thought, but this: http://www.maxi-pedia.com/what+is+heap+and+stack seems to say different? – Wayne Werner Jul 30 '10 at 17:41
  • @Wayne: That entry is, as far as I can tell, garbage. If you know enough to distinguish between the true and false statements, and the ones that just imply something odd, you know enough that you don't need to read something that basic. You're much better off asking questions like yours here, and reading the answers and comments to the answers carefully. – David Thornley Jul 30 '10 at 17:58
  • 1
    Well, the stack/heap thing has always confused the heck out of me -- which one does what -- so even though it struck me as odd, I wasn't confident enough to question it. However, as a result of the multitude of answers I've received, as well as the Wikipedia article, I think I know enough to call BS next time ;) – Wayne Werner Jul 30 '10 at 18:53
7

Your function variables are also on the stack usually, not the heap. In most systems, the heap is used for dynamic allocations. The usual memory leak situation is

  1. Call some function F
  2. F allocates (new or malloc) some memory
  3. F returns to caller (no delete/free)
  4. pointer pointing to the dynamically allocated memory is out of scope
    • the memory is still allocated.
    • You can't delete/free it anymore
µBio
  • 10,668
  • 6
  • 38
  • 56
6

Memory leak made simple: whenever you allocate memory with malloc/new and don't deallocate it later with free/delete after finishing using that memory... will cause a memory leak! The allocated memory will remain there and that space won't be used by your program ever again.

This is a serious problem when the leak is on a function that is called many times, rendering the leak to grow larger and larger each time the function is called.

karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • It's also very hard to find if the leak grows slowly, and hard to debug if the object being leaked is used in multiple locations before it needs deleting! – Brian S Jul 30 '10 at 18:05
4

Think of it this way. When developing in a language that requires the coder to manage memory, you need to explicitly allocate and destroy the memory for every single object your program will use. It's very easy to know when you don't create something properly, as your program will not work. It is much tougher to find and debug the cases where you don't destroy the object properly (this is known as a memory leak).

Lets take a typical application, lets say an RSS news reader. In an application like this, there are often many loops (looping through different RSS feeds, different RSS items, RSS Tags, and so on). If you have an instance where a created object is not properly destroyed (or released), every time that 'leaking' code is run, you will wind up with another abandoned object in memory. If the loop runs 1,000 times, you will have 1,000 abandoned objects taking up space. You can see how this can quickly add up to consume valuable resources.

Dutchie432
  • 28,798
  • 20
  • 92
  • 109
3

In general, automatic variables in functions (subroutines) are going to be stored on the stack as well. Only 'malloc' or 'new' data allocations come from the heap. Next, heap based allocations can be freed and reused (many times) before the end of the program. The allocation system keeps track of both the in-use areas and the freed areas. Finally, a memory leak is when your program has lost track of some allocated memory without freeing it. this can happen by either writing over a pointer with a new value, or storing a pointer in a variable with limited lifetime/scope.

edgman
  • 175
  • 3
3

It looks like you're using C++ code. In C++ local variables are put on the stack (I'm guessing that globals are too, but I'm not sure). So len in your middleLetter function would be put on the call stack as well. I recommend reading this article: http://en.wikipedia.org/wiki/Call_stack

When you use the new operator with a type, like int *x = new int; for example, enough contiguous memory is found to put an int. The pointer that you use to reference it, *x, is a local variable though. If x goes out of scope and you lose your pointer, that does not free the memory on the heap. That memory is still "used" by your program even though you now have no way to reference it. Because you cannot reference it you cannot deallocate it (or delete it).

As you continue to do this you will eventually run out of space on the heap that you can allocate to, and you're program will get close and closer to blowing up because it has no memory to work with among other problems.

Jeremy Pridemore
  • 1,995
  • 1
  • 14
  • 24
  • That was an excellent article. I think I gained some more concrete comprehension about the stack. – Wayne Werner Jul 30 '10 at 17:52
  • 1
    It isn't really defined where global variables (and I include `static` variables here) are. They could be at the bottom of the stack, or in their own little area. Since (at least in C and C++) they're initialized, the odds are it's their own little area. The stack is where variables are created through their functions being called, and not necessarily a general dumping ground. – David Thornley Jul 30 '10 at 18:01
1

A memory leak is simply dynamic memory that you allocate, but then never free. A consequence of this is that your program will slowly eat up memory over time, potentially causing a crash if you completely run out of physical memory and your swap gets completely eaten as well.

So this is technically a memory leak:

int main(void) {
    void *some_memory = malloc(400);

    // rest of program...
    // some_memory is never freed
}

But this is not:

int main(void) {
    void *some_memory = malloc(400);

    // rest of program...
    free(some_memory);
}

Of course, this is a bit of a trivial example. More commonly, memory leaks occur in loops where several chunks of memory are allocated, but not all memory is freed. A common one is if you have a dynamically allocated struct containing a pointer to a dynamically allocated string - if you free the struct but forget to free the string, that is a memory leak. But note that your OS will clean up any allocated memory when your program terminates, so it won't permanently affect your memory.

Dynamically allocating memory with functions such as malloc(), calloc(), and realloc(), but not using free(), will cause a memory leak. When you dynamically allocate memory, it is stored on the heap rather than the stack (the stack is used for static memory allocation such as local variables and the heap is used for dynamic memory allocation). When a function returns, values on the stack memory are reclaimed. However, the heap memory does not get reclaimed.

Finally, leaked memory is memory that is no longer accessible and has not been freed / de-allocated.

Rajesh Prajapati
  • 2,331
  • 1
  • 10
  • 6
0

it's when programmers creat a memory in the heap and forget to delete it memory leaks reduce the performance of the computer and reduce the amount of dynamic memory available so in brief memory leaks happens when a program ask for more and more memory without releasing the memory no longer needs so as always when you finished with the memory allocation you need to release the memory using the free() function

P0MS
  • 43
  • 6
0

In garbage-collected systems, the term "memory leak" can sometimes seem a bit nebulous. I would offer the following definition, which is just as applicable to garbage-collected systems as to those which use explicit deallocation: A program or subprogram P has a memory leak if there exists an initial sequence of inputs S and repeating pattern of inputs P, such that:

  1. Feeding the program or subprogram input S followed by P will leave the program in the same "meaningful" state as it had before P, but
  2. For any quantity of memory Q, there exists some number N of repetitions, such that feeding the program input S followed by N repetitions of P will cause the program to use more than quantity Q of memory.

It is possible for a program without a memory leak to have memory usage which is unbounded with respect to the size of the input, if all of the input is in fact contributing to the program's state. For example, a program to read in an input file and write it out in reverse order will require enough memory to hold the file. On the other hand, a program with a memory leak will require an unbounded amount of memory to handle an infinite input stream, even though the amount of memory required should be finite.

supercat
  • 77,689
  • 9
  • 166
  • 211