Memory leaks can be caused by a variety of problems. Some are easy to detect and can be remedied in a simple way; some are difficult to detect yet can be easily remedied; and some are extremely difficult to detect and remedy.
The orphaned allocation problem applies to both C and C++ programs. Here the pointer to an allocated segment is not stored for later deallocation, but this can be easily rectified when detected and located.
The hidden allocation problem applies to both C and C++ programs and is caused by insufficient knowledge of what is being used - usually in the form of obtaining an object from another module without knowing that the object was allocated on the heap and that it should be deallocated. This problem can be rectified when detected and located, though changes in the code could be significant.
The undetermined ownership problem applies to both C and C++ programs and is caused by poor design and integration - usually in the form of obtaining a dynamic object from another module without assuming the responsibility for its deallocation. This problem can be rectified when detected and located, though changes in the code could be significant.
The insufficient destructor problem applies only to C++ programs. In this case there is usually no explicit destructor provided for a class that has some of its members created dynamically. Though relatively easy to rectify when detected and located, this problem is difficult to detect.
The incorrect assignment problem also applies to C++ programs only and is usually caused by a missing assignment for a class that has some members created dynamically. This problem can be rectified fairly easily once detected and located, but again it is the detection that is difficult.
The exception-unsafe code problem applies only to C++ programs. It usually takes the form of code that, when interrupted by an exception, does not properly clean up whatever has been allocated prior to the exception. This problem is quite difficult to detect and localize, and rectification requires a significant redesign of the code.
The external component problem applies to both C and C++ programs. There is not too much you can do about it besides contacting the external source or working around the problem.
Tracing memory leaks in C programs is relatively easy. Using the preprocessor, all calls to the C allocators and the deallocator can be transformed to calls to their respective debugging versions. These versions can keep track of the location from which they were called and/or log this information, and upon program termination they may display or log statistics concerning what remains undeallocated. Together with the location information, this helps detect and localize memory leaks. For a simple location reference the preprocessing directives __FILE__ and __LINE__ can be used. For a more detailed location reference, the entrances and exits of all functions must be marked by specialized functions that keep a global stack of names of functions being called. With replacement allocators and a replacement deallocator, even leaks in an external C-based object code can be traced.
Tracing memory leaks in C++ programs is much more complex, for two reasons. First, the allocators and deallocators in C++ are not (as in C) standard functions and hence cannot be unplugged and replaced ; they are operators and as such are part of the language. Second, C++ programs may use any mixture of C allocators and the deallocator, global new and delete , class-specific new and delete , their array versions ( new ...) and possibly overloaded versions of all of these. In essence, the first reason explains why you cannot trace memory leaks from an external object code that is written in C++. With regard to the second reason, an approach similar to that used for C programs may be used for C++ programs: new s and some delete s may be overloaded so as to become location-sensitive and provide tracking and/or logging of what has been allocated/deallocated by whom. However, unlike in C, such an effort will probably require significant modifications to the program.
A simple aid in tracing C++ memory leaks one that requires only modest changes in the program and that can easily be turned on and off may be obtained using object counting. Upon termination of the program, we can display or log statistics of how many objects remain undeallocated. The counting can be made location-sensitive (i.e., keeping track not only of how many objects were created but also where and/or when they were created).
The flexibility of C++ can be used to remedy the problem of undetermined ownership through the use of so-called safe or smart pointers. These are implemented in the C++ Standard Library in the form of auto_ptr<X> . Smart pointers are objects that behave like pointers with the additional property that their destructors deallocate the object they reference when the pointers go out of scope. If used in a disciplined way, smart pointers can prevent the undetermined ownership problem and also provide for an exception-safe design.