我正在开发内存泄漏工具。在这里,我重载了新的和删除的运算符。它工作正常。但是我为其创建此工具的代码大约有 15000 行。我无法更改现有代码,只能将 memoryleak 工具函数调用到现有代码中。具有 STL 容器(如列表、 map 、堆栈等)的现有代码。 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 容器出现时,它会给出错误的结果,因为它们只使用重载的新容器。 请帮帮我
最佳答案
从编写这些“空”函数开始。它们将由您自己替换标准的新建和删除:
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 获取调用堆栈并将其存储在每次内存分配中。
有些人可能想知道为什么要这样做而不是使用其他工具:
- 根据我的经验,Visual Studio 中的泄漏报告是有限的。它不显示调用堆栈,只显示直接调用者,这使它变得毫无意义。
- 一些工具使用#define 来替换 new、delete、alloc、...,但这在很多情况下会产生问题(例如,一个类方法被称为 free(在 Qt 中看到这个),或者删除完成在 header 中,但在必须链接的 .lib 中是新的(也在 Qt 中看到))。
- 其他工具需要您制作应用程序的交互式快照,然后再进行比较。在我上面的方法中,您会获得自动泄漏报告(无需手动操作,始终在应用程序结束时,...)。
一旦有了自己的内存管理器,就可以开始考虑添加其他功能(例如,基于调用堆栈的内存统计信息、查找内存覆盖的技巧、查找删除后重用内存的代码的技巧,.. .).
关于c++ - 停止通过 STL 容器调用重载的 new 和 delete 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4944852/