重载new/delete操作符并结合宏定义实现内存分配跟踪,通过记录分配信息检测泄漏与非法释放。

实现一个简单的内存分配跟踪器,能帮助开发者在调试阶段发现内存泄漏、重复释放和非法访问等问题。C++ 没有内置的内存跟踪机制,但我们可以重载全局的 new 和 delete 操作符,在其中插入日志记录逻辑,从而实现基础的跟踪功能。
1. 重载 new 和 delete 操作符
通过重载全局的 new 和 delete,可以拦截所有使用这些操作符的内存申请与释放行为。
示例代码:
#include
#include
2. 定义宏简化调用
直接写 new("file", line) 不现实,可以通过宏自动注入文件名和行号。
#define DEBUG_NEW new(__FILE__, __LINE__)
// 使用时替换 new 为 DEBUG_NEW
#define new DEBUG_NEW
这样写 new MyClass 实际上调用的是带位置信息的 new 版本。
3. 检测内存泄漏
程序结束前检查 g_allocations 是否为空,非空说明存在未释放的内存。
添加一个检测函数:
void check_leaks() {
if (g_allocations.empty()) {
std::cout << "No memory leaks detected.\n";
} else {
std::cout << "Memory leaks detected:\n";
for (const auto& pair : g_allocations) {
std::cout << "LEAK: " << pair.first
<< " size=" << pair.second.size
<< " @ " << pair.second.file
<< ":" << pair.second.line << "\n";
}
}
}
在 main 函数末尾调用 check_leaks() 即可看到结果。
4. 注意事项与扩展
这个简易跟踪器适合学习和小型项目,实际使用需注意:
- 必须同时重载 new[] / delete[] 以支持数组
- 多线程环境下需加锁保护 map
- 性能开销较大,仅用于调试
- 不能检测栈内存或 mmap 分配的内存
- 可扩展为记录调用栈(需平台 API 支持)
基本上就这些。不复杂但容易忽略细节。只要把 new/delete 拦截好,加上位置信息和日志输出,就能构建出一个可用的内存跟踪工具。发布版本记得关闭宏定义避免影响性能。