开发者

Stop calling overloaded new and delete operator by stl containers

I am developing a memoryleak tool. In this i am overloading new and delete operator. Its working fine. But the code for which i am creating this tool is around 15000 lines. I cannot change the existing code only i can invoke the memoryleak tool function into the existing code. Existing code having stl containers (like list, map, stack etc). Stl container also call new and delete operator to allocate or deallocate memory. i want that s开发者_运维问答tl container should call the new and delete operator which are in not the overloaded new and delete. for ex:

int *iptr = new int[10] ----> should call overloaded new[]
delete [] iptr -------------> should call overloaded delete[]
map.insert(10) -------------> should call default new[] ( which are in new.h)
map.erase()  ---------------> should call default delete[] ( which are in new.h)

how can i do it? Any help would be aprreciated.

Sorry i forgot to mention that i am replacing new and delete with the following macros:

#define new DEBUG_NEW
#define DEBUG_NEW TrackMemory(__FILE__, __LINE__) ->* new
#define delete TrackDelete(__FILE__, __LINE__); delete

here TrackMemory is used to track memory and new is used to allocate memory same with delete. my tool also works fine but when stl containers comes into picture then it gives wrong result because they only use overloaded new. please help me out


Starting by writing these 'empty' functions. They will replace the standard new and delete by your own:

void *operator new (size_t memorySize);
void *operator new[] (size_t memorySize);
void *operator new (size_t memorySize, const std::nothrow_t &) throw ();
void *operator new[] (size_t memorySize, const std::nothrow_t &) throw ();
void operator delete (void *memoryPointer);
void operator delete[] (void *memoryPointer);
void operator delete (void *memoryPointer, const std::nothrow_t &) throw ();
void operator delete[] (void *memoryPointer, const std::nothrow_t &) throw ();

Then write separate functions to allocate and deallocate memory:

void *myNew (size-t memorySize);
void myDelete (void *memoryPointer);

Call your myNew and myDelete in the functions mentioned in the beginning.

Implement myNew and myDelete by using HeapAlloc and HeapFree.

Then make a global variable and mark it like this (this is Visual Studio):

#pragma init_seg(lib)

This will make sure your global variable is initialized first, and cleaned up last.

So far, we have covered the basis. To get real leak-reporting-functionality, you will need to store information about allocated memory in your myNew function.

Use the destructor of your global variable to report all leaks.

Additionally, you could use StackWalk to get the call stack and also store this with each memory allocation.

Some will probably wonder why you want to do this instead of using other tools:

  • in my experience, leak reporting in Visual Studio is limited. It doesn't show you the call stack, but only the direct caller, which makes it meaningless.
  • some tools use #define to replace new, delete, alloc, ..., but this can gives problems in quite some cases (e.g. a class method which is called free (seen this in Qt), or the delete is done in a header, but a new in a .lib which must be linked in (also seen in Qt)).
  • other tools require you to make interactive snapshots of your application and compare them afterwards. In my approach above, you get automatic leak reporting (no manual action needed, always at end of the application, ...).

Once you have your own memory manager, you can start thinking about adding other functionality (e.g. memory statistics based on the call stack, tricks to find memory overwrites, tricks to find code that reuses memory after it has been deleted, ...).


15000 lines ? Well, replace all calls to new and delete by calls to wrapper methods in your code (using macros to log __FILE__ and __LINE__ can be a first step) and you'll be done quickly.

Or use an existing tool, like valgrind.


It is not clear what you mean by saying you're overloading operator new. You cannot overload the standard operator new as such, you can only replace it at link time. When you replace it you lose the original ones, which is the stupidest design I have ever seen. The replacement is also global. You can work around this with platform specific linker tricks on some platforms (weak symbols).

You can do some kind of lookup tricks with class based operator new, and of course you can overload operator new on placement arguments, but I assume you mean neither of these.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜