千家信息网

windows下C/C++内存泄露怎么检测

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,这篇文章主要介绍了windows下C/C++内存泄露怎么检测的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇windows下C/C++内存泄露怎么检测文章都会有所收获,下面
千家信息网最后更新 2025年01月20日windows下C/C++内存泄露怎么检测

这篇文章主要介绍了windows下C/C++内存泄露怎么检测的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇windows下C/C++内存泄露怎么检测文章都会有所收获,下面我们一起来看看吧。

检测内存泄露

利用Visual Studio调试器和CRT库提供的检测(malloc和new均适用)

程序只从单一位置退出时:

1.需要以下头文件:

#define _CRTDBG_MAP_ALLOC#include#include

通过包含crtdbg.h,将malloc和free分别映射到_malloc_dbg和_free_dbg,用于内存分配和释放的跟踪。
#define _CRTDBG_MAP_ALLOC语句用于提供额外的信息,非绝对必要。

2.在程序退出位置前使用以下语句:

_CrtDumpMemoryLeaks();

该语句会在输出窗口显示内存泄露信息。

测试代码

#define _CRTDBG_MAP_ALLOC#include#include#include#define NUM 10int main(){    char *test;    test = (char*)malloc(NUM * sizeof(char));    _CrtDumpMemoryLeaks();    return 0;}

输出结果

使用_CRTDBG_MAP_ALLOC时:

未使用_CRTDBG_MAP_ALLOC时:

如果将程序中的:

char *test;test = (char*)malloc(NUM * sizeof(char));

替换为:

char* name = new char[10];

也会得到同样的结果(内存位置由于自动分配有所不同):

程序从多个位置退出时:

1.同样包含上述头文件

2.在每个会退出程序的函数(包括main函数)开始处包含以下代码:

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

程序会在退出时自动调用_CrtDumpMemoryLeaks();。

测试代码

#define _CRTDBG_MAP_ALLOC#include#include#include#define NUM 10void test1();void test2();int main(){    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);    char *test;    test = (char*)malloc(NUM * sizeof(char));    int a;    puts("input a number");    scanf_s("%d", &a, sizeof(int));    if (a > 10)        test1();    else if(a<20)        test2();    else        puts("exit point 3");    return 0;}void test1(){    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);    puts("exit point 1");    exit(EXIT_SUCCESS);}void test2(){    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);    puts("exit point 2");    exit(EXIT_SUCCESS);}

定位内存泄露

当程序不大时,内存泄露位置可以轻易通过肉眼分辨或者代码审计发现。但是当程序较大的时候,就难以发现具体发生内存泄露的位置。此时可以通过CRT库的_CrtMenState结构储存内存状态。

使用该结构类型需要定义变量用于储存内存状态:

_CrtMenState s1,s2,s3;

检测指定位置内存需要用到_CrtMenCheckPoint结构:

_CrtMenCheckPoint(&s1);

该语句将当前位置的内存状态传递到_CrtMenState结构变量s1中。

检测两个位置之间的内存状态需要用到_CrtMenDifference()函数,同时需要一个新的_CrtMenState结构变量用于存储状态之间的差异:

_CrtMemCheckpoint( &s1 );_CrtMemCheckpoint( &s2 );_CrtMemDifference( &s3, &s1, &s2);

转储_CrtMenState结构的内容需要用到_CrtMemDumpStatistics函数:

_CrtMenDumpStatics(&s3);

测试代码

#define _CRTDBG_MAP_ALLOC#include#include#include#define NUM 10_CrtMemState s1, s2, s3;void MEM(char *str, int n);int main(){    _CrtMemCheckpoint(&s1);    char *test=NULL;    MEM(test, NUM);    _CrtMemCheckpoint(&s2);    puts("test\n");    _CrtMemDifference(&s3, &s1, &s2);    _CrtMemDumpStatistics(&s3);    return 0;}void MEM(char *str, int n){    str = (char*)malloc(n * sizeof(char));}

输出结果

当s1和s2之间调用了函数MEN()时:

当删去程序中的

MEN(test, NUM);

即s1和s2之间没有调用MEN()函数时:

如果单纯使用_CrtDumpMemoryLeaks();,只能显示内存分配的位置,即函数MEN()中分配内存语句的位置,而不能定位到是哪一次对函数MEN()调用导致的内存泄露,而通过结构_CrtMenState,可以得到语句之间是否存在内存分配,从而定位出内存泄露的位置。

关于"windows下C/C++内存泄露怎么检测"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"windows下C/C++内存泄露怎么检测"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

0