How can I deal with static objects when overloading new ones and delete to find memory leaks?
I am trying to detect memory leaks by globally reloading new ones and deleting for debug builds and maintaining a list of allocated blocks. This works, but incorrectly reports leaks for some static objects. For example, a static std :: vector itself is not allocated with new and delete, but its internal buffers. Since my detection code is running before the main function returns, the destructors of these objects have not been called yet, so they have not yet deleted their buffers and it looks like a "leak".
The workaround I found was to delete and place new static objects to clear their buffers before checking for leaks:
std::vector<int> f;
f.~std::vector<int>();
new (&f) std::vector<int>();
This is really ugly, although including the cleanup code that is not required seems bad. Is there a way to make my code work after the static is destroyed? (even if it depends on Microsoft)
a source to share
Write a function that empties the list of selected blocks. Call it after static initialization, but before your program starts to allocate whatever you want to keep track of. The first thing in main () is to do this. Of course, you will still see leaks for static vectors that have resized, so you might want to reserve more of them to start in leak detection mode. If the static vector grows steadily over time, then you probably want to know about it and treat it as a leak, even if it's static.
Edit in response to comment:
For example, instead of one central bit of code to destroy all globals during shutdown:
template<typename T>
class Reserve {
Reserve(T &t, typename T::size_type size) {
t.reserve(size);
}
};
static std::vector<int> foo;
static Reserve<std::vector<int> > foo_r(foo, 50);
static std:string bar;
static Reserve<std::string> bar_r(bar, 256);
There might be something you can do with the function template so that type inference gets rid of the need to repeat the type. What about:
template<typename T>
int reserve(T &t, typename T::size_type size) {
t.reserve(size);
return 0;
}
static std::vector<int> foo;
static int foo_r = reserve(foo, 50);
static std:string bar;
static int bar_r = reserve(bar, 256);
a source to share
Place all your leak detection code in another, separate DLL. Then make sure that the code you want to check for leaks depends on the DLL. This allows the loader to do the job of ensuring that the "leak checking DLL" is initialized before everything else, and also unloaded after everything else. This will ensure that your leak checking code runs after all other codes have been unloaded (and the destructors have been called).
This is the method I used when I created the Visual Leak Detector and it seems to work well.
a source to share