讲师中心 微信公众号
AI工具推荐 视频效率加速

c++如何实现简单的内存泄漏排查_c++ 重载new与delete运算符记录【指南】

冬婷小哥_4077

冬婷小哥_4077

发布时间:2025-12-27 14:19:02

|

864人浏览过

|

来源于php中文网

原创

重载 new 和 delete 是排查内存泄漏最直接的手段,因其可在每次分配/释放时插入日志、堆栈捕获或计数逻辑,无需修改业务代码且不依赖外部工具;但须同时覆盖全局及数组版本,并妥善处理 size 获取、线程安全、递归调用与 STL 绕过等问题。

c++如何实现简单的内存泄漏排查_c++ 重载new与delete运算符记录【指南】

为什么重载 new 和 delete 是排查内存泄漏最直接的手段

因为 C++ 标准分配器不记录谁在什么位置申请了多大块内存,而重载全局 new/delete 能在每次分配/释放时插入日志、堆栈捕获或计数逻辑——不需要修改业务代码,也不依赖外部工具(如 Valgrind 或 ASan),适合嵌入式、游戏引擎或无法用调试器的环境。

但要注意:仅重载全局版本(::operator new / ::operator delete)不够,必须同时覆盖数组版本(operator new[] / operator delete[]),否则 new int[10] 类操作会绕过你的监控。

如何安全地重载全局 new 和 delete 并记录调用点

核心是用 __FILE__、__LINE__ 和 backtrace()(Linux)或 CaptureStackBackTrace(Windows)获取上下文。为避免递归调用(比如日志本身 malloc),所有记录逻辑必须使用栈内存或预分配缓冲区。

  • 重载函数必须声明在全局作用域,且不能在头文件中重复定义(加 #pragma once 或 inline 修饰符易出错,建议单独实现于一个 .cpp 文件)
  • 不要在重载函数里调用 std::cout、malloc、new 或任何可能间接触发分配的函数
  • 用静态数组缓存调用栈地址,再用 dladdr(Linux)或 SymFromAddr(Windows)做符号解析;若不想依赖符号表,至少保留 __FILE__ 和 __LINE__
  • 用原子计数器(std::atomic_size_t)统计当前未释放字节数,避免多线程竞争
void* operator new(size_t size) {
    void* ptr = malloc(size);
    if (ptr) {
        static std::atomic_size_t total_allocated{0};
        total_allocated += size;
        fprintf(stderr, "[ALLOC] %p %zu bytes at %s:%d\n", ptr, size, __FILE__, __LINE__);
    }
    return ptr;
}
<p>void operator delete(void* ptr) noexcept {
if (ptr) {
static std::atomic_size_t total_allocated{0};
// 这里无法知道 size —— 实际需配合 malloc_usable_size 或自建映射表
fprintf(stderr, "[FREE] %p\n", ptr);
free(ptr);
}
}

如何补全 size 信息并支持匹配检查

标准 operator delete 不带 size 参数,所以单纯打印 __FILE__/__LINE__ 无法判断哪次 new 没被配对释放。解决方法是维护一张哈希表:以指针为 key,存 size + 分配位置 + 时间戳。

Browser Setup (No-Root Linux)
Browser Setup (No-Root Linux)

在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...

下载

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

  • 哈希表本身必须用 mmap 分配(避免用 new 初始化自己),或用固定大小环形缓冲区 + 线性查找(牺牲精度换安全性)
  • Linux 下可用 malloc_usable_size(ptr) 近似还原 size(仅对 malloc 系分配有效,不适用于自定义对齐或 operator new(std::align_val_t))
  • 启用 C++17 的 operator new(size_t, std::align_val_t) 重载时,必须同步实现对应 delete 版本,否则对齐分配会 fallback 到默认 new,漏监控
  • 程序退出前遍历未释放项,按 size 排序输出 top N 泄漏点,比单纯计数更易定位问题模块

实际使用时最容易忽略的三个坑

很多实现跑起来没报错,但根本抓不到泄漏——不是逻辑错,而是被编译器或运行时绕过了。

  • std::vector、std::string 等 STL 容器默认使用 std::allocator,它内部可能直接调用 malloc 而非 operator new;要彻底监控,得传入自定义 allocator 或用链接期替换(如 LD_PRELOAD)
  • 静态对象构造期间的 new 可能发生在你的重载函数初始化之前,导致首几笔分配丢失;把记录结构体定义为 static 全局变量而非局部 static,可确保优先构造
  • Release 模式下编译器可能内联或优化掉 __FILE__/__LINE__,或把 backtrace 调用整个删掉;务必在 Release 构建中保留 debug info(-g)并禁用相关优化(如 -fno-omit-frame-pointer)

真正有效的内存泄漏定位,从来不是靠“有没有重载”,而是看是否覆盖了所有分配路径、能否还原真实调用上下文、以及是否能在目标环境下稳定复现——其余都是细节。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

相关专题

更多
string转int
string转int

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

5399

2023.08.02

java基础知识汇总
java基础知识汇总

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

5824

2023.10.24

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

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

2464

2024.02.23

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

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

1632

2025.10.17

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

3865

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

1590

2025.09.18

c++ 全局变量
c++ 全局变量

本专题整合了c++全局变量的使用、定义、作用域等等内容,阅读专题下面的文章了解更多详细内容。

199

2026.03.17

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

4094

2025.06.09

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

0

2026.09.30

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn