c++实现对内存泄露的检测——windowns以及ubuntu下

vs2019内存泄露检测的方法(参考文章):https://blog.csdn.net/qq_45662588/article/details/118388328
函数参数说明:https://blog.csdn.net/gongluck93/article/details/78676996

一、windowns下的vs2019的内存泄露检测

底下说明信息可以不用看,是帮助我自己便于理解的,

  1. 将堆信息映射到调试版本:#define CRTDBG_MAP_ALLOC
  2. 增加头文件信息:stdlib.h、crtdbg.h
  3. 实现内存检测方法,虽然说是实现,其实是固定,EnableMemLeakCheck调用了系统的_CrtSetDbgFlag方法:_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF)
    • 设置位(打开),该应用程序可指示调试堆管理器执行特殊的调试操作,包括在应用程序退出时检查内存泄露并报告是否找到任何内存泄露、通过指定已释放的内存块应保留在堆的链接列表中来模拟内存不足情况;
    • _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF)
    • 参数是新状态的标志位,返回的是前一状态的标志位;
    • _CRTDBG_LEAK_CHECK_DF:表示的是如果应用程序未能释放其所分配的所有内存,则生成错误报告
    • _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)以获取当前_crtDbgFlag状态
  4. 内存泄露结尾调用的地方,做一个标记:_CrtDumpMemoryLeaks();
位域 默认 描述
_CRTDBG_ALLOC_MEM_DF 打开 打开:启用调试堆分配并使用内存块类型标识符,例如 _CLIENT_BLOCK。 关闭︰ 将新的分配添加到堆的链接列表,但设置阻止类型设置为**_IGNORE_BLOCK**。 还可以与任何堆频率检查宏组合。
_CRTDBG_CHECK_ALWAYS_DF 关闭 打开︰ 调用_CrtCheckMemory在每次分配和解除分配请求。 关闭:必须显式调用 _CrtCheckMemory。 设置此标志后,堆频率检查宏不会产生任何影响。
_CRTDBG_CHECK_CRT_DF 关闭 打开:包括泄漏检测和内存状态差异操作中的 _CRT_BLOCK 类型。 关闭:这些操作将忽略运行时库在内部使用的内存。 还可以与任何堆频率检查宏组合。
_CRTDBG_DELAY_FREE_MEM_DF 关闭 打开︰ 将已释放的内存块在堆链接列表中,将它们分配**_FREE_BLOCK**键入,然后使用字节值 0xDD 填充它们。 关闭:不要将已释放的块保留在堆链接列表中。 还可以与任何堆频率检查宏组合。
_CRTDBG_LEAK_CHECK_DF 关闭 打开︰ 执行自动泄露检查在程序退出时通过调用_CrtDumpMemoryLeaks ,则生成错误报告,如果应用程序未能释放其所分配的所有内存。 关闭:不要在程序退出时自动执行泄露检查。 还可以与任何堆频率检查宏组合

函数名助记
CRT就是标准的C函数,Alloc表示的是返回一个指向n个连续字符存储单元的指针,
Dump表示的是垃圾

1. 先检测是哪一块内存泄露

增加了

#define CRTDBG_MAP_ALLOC  
#include <stdlib.h>  
#include <crtdbg.h>  
//在入口函数中包含 _CrtDumpMemoryLeaks();  
//即可检测到内存泄露

//定义函数:
inline void EnableMemLeakCheck()
{
    
    
	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}
//该函数可以放在主函数的任意位置,都能正确的触发内存泄露输出


//以如下测试函数为例:
int main()
{
    
    
	EnableMemLeakCheck();
	char* pChars = new char[10];
	_CrtDumpMemoryLeaks();
	return 0;
}

如图所示可以看出是191次申请内存没有被释放,产生了内存泄露。
在这里插入图片描述

2. 追踪异常

根据前面第几次内存申请,我们可以进行如下设置:

  1. 同样的映射标志;
  2. 同样的头文件包含
  3. 将内存泄露检测的函数EnableMemLeakCheck换为_CrtSetBreakAlloc(第几次内存申请);
#define CRTDBG_MAP_ALLOC  
#include <stdlib.h>  
#include <crtdbg.h>  

int main()
{
    
    
	_CrtSetBreakAlloc(191);
	char* pChars = new char[10];
	_CrtDumpMemoryLeaks();
	return 0;
}

运行之后如图所示,会将内存泄露的申请内存的地方调试界面调出来,其实就是保存了那时候的堆栈信息
在这里插入图片描述

二、linux下使用clion进行内存泄露的检查

在linux有成熟免费的产品valgrind使用,专门用于检测内存泄漏,并且可以直接追踪到相关的位置,并且在clion中还集成了该工具,打一下广告,windonws下c++开发推荐vs2022,而linux下就推荐clion,并且clion是可以远程服务器,如果有本地服务器也推荐使用clion。

1. 环境使用

ubuntu20下进行安装(其他版本版本也是没有问题的)

2. 安装

sudo apt install valgrind

3. 在clion中进行设置

进入设置中进行设置,setting–>构建–>动态分析–>valgrind

  • 不过在ubuntu里会自动设置好,通过apt安装的就和默认的一样;
    在这里插入图片描述

4. 运行

通过valgrind而不是平时的那个,按照1/2步骤就可以完成内存泄漏检测分析

  1. 运行
  2. 查看结果
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42295969/article/details/127332865