详解windows下C/C++的内存泄露检测

 更新时间:2021年06月09日 11:09:07   作者:lsgxeva  
C/C++由于其没有垃圾回收机制,所以内存的释放一直以来都依靠于程序员的手工释放,因此极其容易出现内存泄露的问题,而在比较大的程序之中,查找内存泄露是一件比较困难的事情,所以我们需要一些简便的方法来检测内存泄露,避免内存泄露导致设备崩溃

检测内存泄露

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

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

1.需要以下头文件:

#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>

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

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

_CrtDumpMemoryLeaks();

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

测试代码

#define _CRTDBG_MAP_ALLOC
#include<stdio.h>
#include<stdlib.h>
#include<crtdbg.h>
#define NUM 10

int 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<stdio.h>
#include<stdlib.h>
#include<crtdbg.h>
#define NUM 10

void 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<stdio.h>
#include<stdlib.h>
#include<crtdbg.h>
#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,可以得到语句之间是否存在内存分配,从而定位出内存泄露的位置。

总结

内存泄露的原因很简单,无非就是分配了内存而没有释放,为了解决这个问题,除了养成良好的习惯,还有要善用工具在编写程序的时候实时监测是否出现内存泄露,减少后期排bug时的工作量。

以上就是详解windows下C/C++的内存泄露检测的详细内容,更多关于windows下C/C++的内存泄露检测的资料请关注脚本之家其它相关文章!

相关文章

  • C语言中的常量详解

    C语言中的常量详解

    本文主要讲解C语言 常量,这里整理了 C语言常量的基础知识,并附代码示例和示例详细讲解,希望能帮助开始学习C 语言的同学
    2021-09-09
  • C语言实现电话簿项目

    C语言实现电话簿项目

    这篇文章主要为大家详细介绍了C语言实现电话簿项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • C/C++中的OpenCV读取视频与调用摄像头

    C/C++中的OpenCV读取视频与调用摄像头

    这篇文章主要介绍了C/C++中的OpenCV读取视频与调用摄像头,具有很好的参考价值,希望对大家有所帮助。
    2022-11-11
  • C语言 设计模式之访问者模式

    C语言 设计模式之访问者模式

    这篇文章主要介绍了C语言 设计模式之访问者模式的相关资料,需要的朋友可以参考下
    2017-01-01
  • c语言实现数组循环左移m位

    c语言实现数组循环左移m位

    这篇文章主要介绍了c语言实现数组循环左移m位,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C语言计算分段函数问题

    C语言计算分段函数问题

    这篇文章主要介绍了C语言计算分段函数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C语言关键字大全(共32个)

    C语言关键字大全(共32个)

    这篇文章主要分享下C语言的32个关键字,需要的朋友可以参考下
    2013-07-07
  • 基于Qt播放器的实现详解(支持Rgb,YUV格式)

    基于Qt播放器的实现详解(支持Rgb,YUV格式)

    这篇文章主要为大家详细介绍了如何利用Qt实现简易的播放器,可以支持支持Rgb,YUV格式。文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下
    2022-12-12
  • C++动态内存管理详解

    C++动态内存管理详解

    今天小编就为大家分享一篇关于关于C++动态分配内存的介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2021-08-08
  • C语言全方位讲解指针的使用

    C语言全方位讲解指针的使用

    指针是C语言中一个非常重要的概念,也是C语言的特色之一。使用指针可以对复杂数据进行处理,能对计算机的内存分配进行控制,在函数调用中使用指针还可以返回多个值
    2022-04-04

最新评论