首页 > 后端开发 > C++ > 正文

C++怎么实现一个简单的内存泄漏检测工具_C++重载new和delete操作符

裘德小鎮的故事
发布: 2025-11-25 16:58:48
原创
645人浏览过
通过重载new/delete并记录分配信息,可实现内存泄漏检测,在程序结束时报告未释放内存块。

c++怎么实现一个简单的内存泄漏检测工具_c++重载new和delete操作符

在C++开发中,内存泄漏是常见问题。通过重载全局的newdelete操作符,我们可以实现一个简单的内存泄漏检测工具,记录每次内存分配与释放的信息,并在程序结束时报告未释放的内存块。

重载new和delete操作符

要实现内存检测,我们需要替换默认的newdelete行为,在分配和释放内存时插入日志记录逻辑。

以下是一个基本实现:

// MemoryTracker.h
#include <iostream>
#include <map>
#include <string>
<p>struct AllocInfo {
size_t size;
const char* file;
int line;
};</p><p>// 全局映射表,记录当前未释放的内存
extern std::map<void*, AllocInfo> g_allocations;</p><p>// 重载 new 操作符
void<em> operator new(size_t size, const char</em> file, int line);
void<em> operator new[](size_t size, const char</em> file, int line);</p><p>// 普通 new 的重载(无文件行号)
void<em> operator new(size_t size);
void</em> operator new[](size_t size);</p><p>// 重载 delete 操作符
void operator delete(void<em> ptr) noexcept;
void operator delete[](void</em> ptr) noexcept;</p><p>// 打印内存泄漏报告
void printMemoryLeaks();</p>
登录后复制

// MemoryTracker.cpp

立即学习C++免费学习笔记(深入)”;

#include "MemoryTracker.h"
#include <iostream>
<p>std::map<void*, AllocInfo> g_allocations;</p><p>void<em> operator new(size_t size, const char</em> file, int line) {
void* ptr = malloc(size ? size : 1); // 防止 new(0)
if (ptr) {
g_allocations[ptr] = {size, file, line};
}
return ptr;
}</p><p>void<em> operator new[](size_t size, const char</em> file, int line) {
return operator new(size, file, line);
}</p><p>void* operator new(size_t size) {
return operator new(size, "unknown", 0);
}</p><p>void* operator new[](size_t size) {
return operator new[](size, "unknown", 0);
}</p><p>void operator delete(void* ptr) noexcept {
if (ptr == nullptr) return;
auto it = g_allocations.find(ptr);
if (it != g_allocations.end()) {
g_allocations.erase(it);
}
free(ptr);
}</p><p>void operator delete[](void* ptr) noexcept {
operator delete(ptr);
}</p><p>void printMemoryLeaks() {
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 << "Address: " << pair.first
<< " Size: " << pair.second.size
<< " File: " << pair.second.file
<< " Line: " << pair.second.line << "\n";
}
}
}</p>
登录后复制

使用宏简化调用

为了自动传入文件名和行号,我们可以定义宏来替换new关键字。

在项目中包含头文件后,添加如下宏定义:

爱图表
爱图表

AI驱动的智能化图表创作平台

爱图表 305
查看详情 爱图表
#define new new(__FILE__, __LINE__)
登录后复制

这样所有使用new的地方都会携带位置信息。注意:这个宏会影响整个翻译单元,建议只在需要检测的源文件中局部启用。

实际使用示例

下面是一个测试例子:

#include "MemoryTracker.h"
<p>// 启用带位置信息的 new</p><h1>define new new(<strong>FILE</strong>, <strong>LINE</strong>)</h1><p>int main() {
int<em> p1 = new int(42);
int</em> p2 = new int[10];</p><pre class='brush:php;toolbar:false;'>delete[] p2; // 正确释放
// delete p1; // 故意遗漏,制造泄漏

printMemoryLeaks(); // 程序退出前调用
return 0;
登录后复制

}

运行结果会显示类似:

Memory leaks detected:
Address: 0x7fb1c8c00000 Size: 4 File: main.cpp Line: 7
登录后复制

注意事项与限制

这种简单检测工具有几个要点需要注意:

  • 必须确保printMemoryLeaks()在程序退出前被调用,最好放在main函数末尾或使用atexit()注册
  • #define new可能影响标准库或其他第三方代码,应谨慎使用范围
  • 不支持placement new等高级用法
  • 多线程环境下需要加锁保护g_allocations
  • 无法检测堆对象或资源泄漏(如文件句柄)

基本上就这些。这个轻量级方案适合学习和小型项目。对于生产环境,推荐使用Valgrind、AddressSanitizer等专业工具。不过自己动手实现一遍,有助于深入理解C++内存管理机制。

以上就是C++怎么实现一个简单的内存泄漏检测工具_C++重载new和delete操作符的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号