0

0

C++如何实现简单的内存泄漏监控器_C++重载new和delete运算符【高级】

尼克

尼克

发布时间:2026-02-08 10:17:02

|

142人浏览过

|

来源于php中文网

原创

c++如何实现简单的内存泄漏监控器_c++重载new和delete运算符【高级】

为什么重载 operator newoperator delete 是监控内存泄漏的最直接方式

因为所有用 newdelete 分配/释放的堆内存,都会经过这两个函数(除非显式调用 malloc/free 或禁用全局重载)。不侵入业务代码、不依赖编译器插桩、也不需要链接额外库——只要重载它们,就能在分配时记下地址+大小+调用,在释放时抹除记录。最终程序退出前未被抹除的条目,就是潜在泄漏点。

注意:必须同时重载带 std::size_t 参数的 operator newoperator delete,以及带 noexcept 的版本(C++11 起默认加),否则某些 STL 容器或异常路径下的分配可能绕过你的监控。

如何在重载中安全记录调用栈和分配信息

仅记录 __FILE____LINE__ 远不够——同一行多次 new 无法区分;而完整调用栈能定位到真正申请位置。推荐用 backtrace()(Linux/glibc)或 CaptureStackBackTrace()(Windows)获取帧地址,再用 backtrace_symbols()SymFromAddr() 解析符号。但要注意:

  • backtrace() 在信号处理函数中不安全,不要在 SIGSEGV 处理里调用
  • 解析符号需链接 -lbfd -ldl(Linux)或初始化 dbghelp.dll(Windows),且调试信息必须存在(-g 编译)
  • 频繁调用栈采集开销大,建议只在 DEBUG 模式启用,或加运行时开关控制

示例关键片段:

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

快剪辑
快剪辑

国内⼀体化视频⽣产平台

下载
void* operator new(std::size_t size) {
    void* ptr = malloc(size);
    if (ptr) {
        record_allocation(ptr, size, __FILE__, __LINE__);
    }
    return ptr;
}

为什么必须重载数组版本的 operator new[]operator delete[]

因为 new T[N]delete[] p 调用的是独立的运算符,不是普通 new/delete。漏掉它们会导致数组分配被记录、但释放时不匹配,误报为泄漏。更隐蔽的问题是:如果只重载了单对象版本,而用户写了 new int[10],编译器会调用默认的 operator new[](可能直接转给 malloc),你的监控完全失效。

务必成对实现:

  • void* operator new[](std::size_t size)
  • void operator delete[](void* ptr) noexcept
  • (可选)带 std::align_val_t 的 C++17 对齐版本,否则对 aligned_new 无感知

程序退出时如何可靠触发泄漏报告而不引发二次崩溃

不能依赖全局对象析构顺序(不确定)、也不能靠 atexit() 中做复杂操作(此时堆可能已部分损坏)。稳妥做法是:

  • main() 返回前手动调用 dump_leaks()
  • 或用静态局部变量 + 析构函数,但确保该变量定义在 main 所在编译单元(避免跨 TU 初始化顺序问题)
  • 报告时禁止调用 std::cout(可能已被销毁),改用 write(2, ...)OutputDebugString()
  • 遍历未释放记录时,跳过已 free 但未 delete 的指针(比如混用 malloc/delete)——这类属于 UB,不归监控器管

真正容易被忽略的是:线程局部存储(TLS)中的分配。若监控器用 thread_local 记录,主线程退出后其他线程仍在运行,数据可能被重复报告或访问已释放内存。统一走全局哈希表 + 读写锁更稳妥。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1515

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

236

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

127

2025.10.17

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

626

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

552

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

173

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

205

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

180

2023.11.23

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

39

2026.02.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.7万人学习

Git 教程
Git 教程

共21课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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