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

c++怎么实现一个简单的内存泄漏检测器_C++中手写轻量内存泄漏检测工具实现

下次还敢
发布: 2025-11-01 12:38:02
原创
359人浏览过
答案是手写内存泄漏检测器可通过重载malloc和free记录内存分配信息。1. 重载内存分配函数,记录每次malloc/new和free/delete的调用堆栈与大小;2. 程序结束时输出未释放的内存块地址、大小及分配位置,实现简单检测。

c++怎么实现一个简单的内存泄漏检测器_c++中手写轻量内存泄漏检测工具实现

在C++开发中,内存泄漏是常见问题。虽然有Valgrind、AddressSanitizer等强大工具,但在某些嵌入式环境或需要轻量级方案时,手写一个简单的内存泄漏检测器很有价值。下面介绍如何实现一个基础但实用的内存泄漏检测工具。

原理与设计思路

核心思想是在程序运行期间记录每一次mallocfree(或new)操作,通过重载内存管理函数,在调用前后插入日志记录逻辑。程序退出前输出未释放的内存块信息。

主要功能包括:

  • 拦截new/操作
  • 记录分配地址、大小、调用位置(文件名、行号)
  • 程序结束时打印未释放的内存

重载 new 和 delete 操作符

在全局作用域中重载operator new,可以捕获所有使用new的内存操作。

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

#include <cstdio>
#include <cstdlib>
#include <map>
#include <string>
<p>struct AllocInfo {
size_t size;
const char* file;
int line;
};</p><p>std::map<void*, AllocInfo> g_allocations;</p><p>void<em> operator new(size_t size, const char</em> file, int line) {
void* ptr = std::malloc(size);
if (ptr) {
g_allocations[ptr] = {size, file, line};
}
return ptr;
}</p><p>void* operator new(size_t size) {
// 如果没有使用宏包装,默认标记为 unknown
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);
}
std::free(ptr);
}</p>
登录后复制

定义宏简化使用

直接写new(file, line)语法不合法,需要用宏替换new表达式。

#define new new(__FILE__, __LINE__)
登录后复制

这样所有使用new的地方都会自动带上文件名和行号。注意这个宏会影响整个翻译单元,建议只在测试构建中启用。

火龙果写作
火龙果写作

用火龙果,轻松写作,通过校对、改写、扩展等功能实现高质量内容生产。

火龙果写作106
查看详情 火龙果写作

示例代码:

int main() {
    int* p1 = new int(42);                    // 被捕获
    int* p2 = new int[100];                   // 注意:数组版本需额外重载
<pre class='brush:php;toolbar:false;'>delete[] p2;                              // 正常释放
// delete p1;                            // 故意漏掉,制造泄漏

// 程序结束前输出泄漏
for (const auto& alloc : g_allocations) {
    printf("Leak: %p, size=%zu, at %s:%d\n",
           alloc.first, alloc.second.size,
           alloc.second.file, alloc.second.line);
}

return 0;
登录后复制

}

运行后会输出类似:

Leak: 0x7f9a80c00000, size=4, at main.cpp:20

支持数组 new/delete[]

上面例子中new int[100]不会被拦截,因为调用了。需要补充重载:

void* operator new[](size_t size, const char* file, int line) {
    void* ptr = std::malloc(size);
    if (ptr) {
        g_allocations[ptr] = {size, file, line};
    }
    return ptr;
}
<p>void* operator new[](size_t size) {
return ::operator new[](size, "unknown", 0);
}</p><p>void operator delete[](void* ptr) noexcept {
::operator delete(ptr);
}</p>
登录后复制

注意:标准允许为空实现,实际调用的是普通,所以复用已有逻辑即可。

注意事项与局限性

这个检测器适用于开发调试阶段,有几点需要注意:

  • 仅捕获new/,不处理(可类似扩展)
  • 宏替换可能影响第三方库代码,建议封装头文件并控制作用范围
  • 多线程环境下需加锁保护
  • 不能检测越界、重复释放等其他内存错误

基本上就这些。不复杂但容易忽略细节。适合集成到小型项目或学习内存管理机制。

以上就是c++++怎么实现一个简单的内存泄漏检测器_C++中手写轻量内存泄漏检测工具实现的详细内容,更多请关注php中文网其它相关文章!

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

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

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

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