新闻中心
C++怎么实现一个简单的内存泄漏检测工具_C++重载new和delete操作符
通过重载new/delete并记录分配信息,可实现内存泄漏检测,在程序结束时报告未释放内存块。

在C++开发中,内存泄漏是常见问题。通过重载全局的new和delete操作符,我们可以实现一个简单的内存泄漏检测工具,记录每次内存分配与释放的信息,并在程序结束时报告未释放的内存块。
重载new和delete操作符
要实现内存检测,我们需要替换默认的new和delete行为,在分配和释放内存时插入日志记录逻辑。
以下是一个基本实现:
// 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
#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 = mallo
c(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关键字。
在项目中包含头文件后,添加如下宏定义:
#define new new(__FILE__, __LINE__)
这样所有使用new的地方都会携带位置信息。注意:这个宏会影响整个翻译单元,建议只在需要检测的源文件中局部启用。
美图云修
商业级AI影像处理工具
50
查看详情
实际使用示例
下面是一个测试例子:
#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操作符的详细内容,更多请关注其它相关文章!
# 多线程
# 西北关键词排名有必要吗
# 酒业产品营销推广方案
# 牙膏的营销推广
# 绥德抖音seo优化
# 立金哥seo
# 株洲全网网络推广seo
# seo蜘蛛推广
# 巴彦淖尔商机网站建设
# 游泳馆营销推广措施
# 洪梅网络营销推广价格
# 句柄
# 放在
# 有什么区别
# 结束时
# 工具
# 是一个
# 如何实现
# 如何使用
# 美图
# 行号
# 标准库
# c++开发
# 常见问题
# stream
# ios
# c++
# ai
# 栈
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南
Win11怎么隐藏桌面图标 Win11一键隐藏所有桌面元素及恢复显示
抖音小游戏合成大西瓜免费秒玩入口链接 抖音小游戏热门合集秒玩网站
AO3最新入口2025公告_AO3中文官网合集
Sublime Text怎么显示空格和制表符_Sublime显示不可见字符设置
谷歌邮箱网页版官方页面入口 谷歌邮箱网页端快速访问
Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议
b站怎么删除评论_b站评论管理与删除操作
支付宝如何管理隐私设置_支付宝隐私保护的配置技巧
Promise错误处理:在catch后终止链式then执行的策略
Win11怎么查看电脑配置_Win11硬件配置检测工具使用
千牛数据看板网页版_千牛数据看板网页版访问方法
LocoySpider如何部署到云服务器_LocoySpider云部署的远程配置
神经网络二分类模型训练异常:高损失与完美验证准确率的排查与修正
顺丰快递查询系统 官方正版查询入口
在J*a中如何开发简易博客标签推荐系统_博客标签推荐项目实战解析
CSS Box Model与弹性按钮:维持布局稳定的动画实践
Angular响应式表单:实现提交后表单及按钮的禁用与只读化
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
Python字典中优雅地迭代剩余元素的方法
Mac怎么使用表情符号_Mac Emoji快捷键面板
2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享
Go与Ruby之间实现AES加密互通:CFB模式下的密钥长度匹配策略
taptap防沉迷怎么解除 taptap解除健康系统限制说明【2025最新】
uc浏览器网页版入口 uc浏览器网页版最新网址
4399免费游戏网址入口 4399小游戏免费入口点开即玩
俄罗斯浏览器官网直达链接 俄罗斯浏览器最新在线入口导航
如何修改开机登录密码_Windows账户安全设置超详细教程【必学】
在J*a中如何开发在线活动报名与管理系统_活动报名管理项目实战解析
微信网页版官方快速登录入口 微信网页版网页版账号直达
小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口
J*aScript中高效管理与清空动态列表:避免循环陷阱
最新韩小圈网页版登录入口_官网在线观看官方链接
c++20的std::jthread是什么_c++可中断线程与RAII式管理
必由学官网入口 必由学教师登录入口
LINUX的I/O重定向是什么_深入理解LINUX中 >、>> 与 < 的区别
优化Log4j2控制台输出性能:解决异步日志瓶颈
蓝湖怎样用切图标注提对接效率_蓝湖用切图标注提对接效率【设计对接】
Golang如何优雅处理error_Golang error处理最佳实践总结
反效果?《战地6》免费试玩开启后玩家数不升反降
Django模型中自动计算可用余额的实现方法
Pandas DataFrame 多条件优先级排序与排名
windows10怎么关闭系统提示音_windows10彻底静音设置方法
Windows10怎么开启存储感知 Windows10系统设置自动清理临时文件释放C盘空间【教程】
《噬血代码2》新预告片发布 展示游戏剧情
lar*el怎么安全地存储和获取配置文件中的敏感信息_lar*el敏感信息安全存储方法
如何在离线环境中使用Composer_Composer离线安装依赖包的技巧与策略
c++中的std::forward_list和std::list有什么不同_c++ forward_list与list区别分析
CSS如何设置hover状态颜色_hover伪类调整背景或文字颜色
如何在J*a中使用Locale处理多语言环境


2025-11-25
浏览次数:次
返回列表
c(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>