Memory management mistakes to avoid
Excerpts from http://www.memorymanagement.org/
The basic problem in managing memory is knowing when to keep the data it contains, and when to throw it away so that the memory can be reused. This sounds easy, but is, in fact, such a hard problem that it is an entire field of study in its own right. In an ideal world, most programmers wouldn't have to worry about memory management issues. Unfortunately, there are many ways in which poor memory management practice can affect the robustness and speed of programs, both in manual and in automatic memory management. Typical problems include:
Premature free or dangling pointer
Many programs give up memory, but attempt to access it later and crash or behave randomly. This condition is known as premature free, and the surviving reference to the memory is known as a dangling pointer. This is usually confined to manual memory management.
Memory leak
Some programs continually allocate memory without ever giving it up and eventually run out of memory. This condition is known as a memory leak.
External fragmentation
A poor allocator can do its job of giving out and receiving blocks of memory so badly that it can no longer give out big enough blocks despite having enough spare memory. This is because the free memory can become split into many small blocks, separated by blocks still in use. This condition is known as external fragmentation.
Poor locality of reference
Another problem with the layout of allocated blocks comes from the way that modern hardware and operating system memory managers handle memory: successive memory accesses are faster if they are to nearby memory locations. If the memory manager places far apart the blocks a program will use together, then this will cause performance problems. This condition is known as poor locality of reference.
Inflexible design
Memory managers can also cause severe performance problems if they have been designed with one use in mind, but are used in a different way. These problems occur because any memory management solution tends to make assumptions about the way in which the program is going to use memory, such as typical block sizes, reference patterns, or lifetimes of objects. If these assumptions are wrong, then the memory manager may spend a lot more time doing bookkeeping work to keep up with what's happening.
Interface complexity
If objects are passed between modules, then the interface design must consider the management of their memory.
A well-designed memory manager can make it easier to write debugging tools, because much of the code can be shared. Such tools could display objects, navigate links, validate objects, or detect abnormal accumulations of certain object types or block sizes.
Typical memory management mistakes in C
Memory management in C is typically manual, the standard library functions for memory(2) management in C, malloc and free(2), have become almost synonymous with manual memory management.
The language is notorious for fostering large numbers of memory management bugs, including:
- Accessing arrays with indexes that are out of bounds;
- Using stack-allocated structures beyond their lifetimes (a.k.a use after free);
- Using heap-allocated structures after freeing them (see use after free);
- Neglecting to free heap-allocated objects when they are no longer required (a.k.a memory leak);
- Failing to allocate memory for a pointer before using it;
- Allocating insufficient memory for the intended contents;
- Loading from allocated memory before storing into it;
- Dereferencing non-pointers as if they were pointers.

Comment