0

0

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

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-11-25 16:58:48

|

674人浏览过

|

来源于php中文网

原创

通过重载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关键字。

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

Glimmer Ai
Glimmer Ai

基于GPT-3和DALL·E2的PPT制作工具

下载
#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++内存管理机制。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

119

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

389

2023.10.11

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

443

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

605

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

443

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

605

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

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

精品课程

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

共58课时 | 6万人学习

ASP 教程
ASP 教程

共34课时 | 5.9万人学习

Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.6万人学习

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

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