memory allocation logging for leak detection - problem with globals

S

Spur

Hi all,

I implemented a memory allocation/deallocation class that logs all
new/delete calls (overloaded) and remembers for each allocated
block where it was allocated from (using a macro that passes __FILE__
and __LINE__). On destruction, it reports all undeleted blocks
(memory leaks).

The class is implemented in a separate .h/.cpp pair, and should be
linked to
code when I want to use it (plus a #define should be set and the
header should be included).

It works nicely, except for one problem - global objects. There is
one global instance of the logging class in the .cpp file, and it
catches all memory leaks from inside main() just fine. It misbehaves
with global objects - reporting many false alarms.

I'm aware of the fact that the order of construction/destruction of
global objects (in different files) is not specified by the standard.
However, I still wonder whether it's possible to implement this
somehow portably ? Non-portably (after all, checking for memory leaks
on one platform should be enough, I think...) ?

If not, it would be another good reason to never use globals B-)

Thanks in advance
Eli
 
H

Howard Hinnant

Hi all,

I implemented a memory allocation/deallocation class that logs all
new/delete calls (overloaded) and remembers for each allocated
block where it was allocated from (using a macro that passes __FILE__
and __LINE__). On destruction, it reports all undeleted blocks
(memory leaks).

The class is implemented in a separate .h/.cpp pair, and should be
linked to
code when I want to use it (plus a #define should be set and the
header should be included).

It works nicely, except for one problem - global objects. There is
one global instance of the logging class in the .cpp file, and it
catches all memory leaks from inside main() just fine. It misbehaves
with global objects - reporting many false alarms.

I'm aware of the fact that the order of construction/destruction of
global objects (in different files) is not specified by the standard.
However, I still wonder whether it's possible to implement this
somehow portably ? Non-portably (after all, checking for memory leaks
on one platform should be enough, I think...) ?

If not, it would be another good reason to never use globals B-)

I've coded similar tools:

http://home.twcny.rr.com/hinnant/MemoryManager/

The approach I took was to implement my global memory allocator with a
simplistic singleton pattern (a function local static accessbile via a
returned reference). This isn't perfect, but it tends to work well in a
wide variety of circumstances. When a global constructor fires (before
main), and tries to allocate some memory, it will trigger the
construction of the global memory allocator before its own constructor
completes. At program termination, leak checking is done in the
destructor of the global memory allocator. With luck your allocator's
destructor will run after there is any more legitimate heap activity
occurring.

Note that there are situations where this design fails, most notably if
a global constructor runs before the memory allocator gets constructed
and does not allocate memory at that time, but then allocates memory
later in its lifetime. Its destructor will run after the allocator's
destructor has run, and thus will be freeing memory to an already
destructed allocator which has already flagged that memory as leaked.

So it's not perfect, but it tends to work fairly well in practice. In a
problem situation you could have the global "preflight" the debugging
allocator by allocating some memory in its constructor even though it
didn't need to.

There may also be an implementation defined way of ordering your global
constructors. I used to use this technique with my debugging allocator.
However after using that technique for a few years I finally changed to
the local static design because it was less of a pain in the rear to use
for the type of code I needed to monitor.

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top