我正在开发一个memoryleak工具。在这我正在重载new和delete运算符。它的工作正常。但我创建此工具的代码大约是15000行。我无法更改现有代码,只能将memoryleak工具函数调用到现有代码中。具有stl容器的现有代码(如列表,映射,堆栈等)。 Stl容器还调用new和delete运算符来分配或释放内存。我希望stl容器应该调用new和delete运算符,它们不是重载的new和delete。 例如:
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)
我该怎么办? 任何帮助都会受到重视。
抱歉,我忘了提到我正在用以下宏替换new和delete:
#define new DEBUG_NEW
#define DEBUG_NEW TrackMemory(__FILE__, __LINE__) ->* new
#define delete TrackDelete(__FILE__, __LINE__); delete
这里TrackMemory用于跟踪内存,new用于分配与delete相同的内存。 我的工具也可以正常工作但是当stl容器进入图片时它会产生错误的结果,因为它们只使用重载的新的。 请帮帮我
答案 0 :(得分:2)
15000行?好吧,通过调用代码中的包装器方法替换对new
和delete
的所有调用(使用宏来记录__FILE__
和__LINE__
可以是第一步)并且你'我会很快完成的。
或使用现有工具,例如 valgrind 。
答案 1 :(得分:2)
首先编写这些'空'函数。他们将替换标准的new并自行删除:
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 ();
然后编写单独的函数来分配和释放内存:
void *myNew (size-t memorySize);
void myDelete (void *memoryPointer);
在开头提到的功能中调用myNew和myDelete。
使用HeapAlloc和HeapFree实现myNew和myDelete。
然后创建一个全局变量并将其标记为(这是Visual Studio):
#pragma init_seg(lib)
这将确保您的全局变量首先被初始化,并最后清理。
到目前为止,我们已经覆盖了基础。要获得真正的泄漏报告功能,您需要在myNew函数中存储有关已分配内存的信息。
使用全局变量的析构函数来报告所有泄漏。
此外,您可以使用StackWalk获取调用堆栈,并将其存储在每个内存分配中。
有些人可能想知道为什么要这样做而不是使用其他工具:
一旦拥有了自己的内存管理器,就可以开始考虑添加其他功能(例如,基于调用堆栈的内存统计,查找内存覆盖的技巧,查找在删除内存后重用内存的代码的技巧,... )。
答案 2 :(得分:0)
通过说你的操作员新载重载,你的意思并不清楚。您不能将标准运算符重载为新,因此只能在链接时替换它。当你更换它时,你将失去原有的,这是我见过的最愚蠢的设计。替代也是全球性的。您可以在某些平台(弱符号)上使用特定于平台的链接器技巧解决此问题。
您可以使用基于类的operator new执行某种查找技巧,当然您可以在放置参数上重载operator new,但我认为您的意思不是这两种。