Try Valgrind (it’s free, open-source):
The Valgrind distribution currently
includes six production-quality tools:
a memory error detector, two thread
error detectors, a cache and
branch-prediction profiler, a
call-graph generating cache profiler,
and a heap profiler. It also includes
two experimental tools: a
heap/stack/global array overrun
detector, and a SimPoint basic block
vector generator. It runs on the
following platforms: X86/Linux,
AMD64/Linux, PPC32/Linux, PPC64/Linux,
and X86/Darwin (Mac OS X).
The Memcheck part of the package is probably the place to start:
Memcheck is a memory error detector.
It can detect the following problems
that are common in C and C++ programs.
Accessing memory you shouldn’t, e.g. overrunning and underrunning heap
blocks, overrunning the top of the
stack, and accessing memory after it
has been freed.
Using undefined values, i.e. values that have not been initialised, or
that have been derived from other
Incorrect freeing of heap memory, such as double-freeing heap blocks, or
mismatched use of malloc/new/new
Overlapping src and dst pointers in memcpy and related functions.