我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解windows下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++的内存泄露检测的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

windows下C/C++内存泄露检测的方法

小编给大家分享一下windows下C/C++内存泄露检测的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!检测内存泄露利用Visual Studio调试器和CR
2023-06-15

C/C++实现内存泄漏检测详解

这篇文章主要为大家详细介绍了c++进行内存泄漏检测的方法,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下,希望能够给你带来帮助
2023-02-09

C++中如何检查内存泄露

这篇文章给大家介绍C++中如何检查内存泄露,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、前言在Linux平台上 有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器
2023-06-17

golang函数内存泄露检测与解决

go 语言中存在函数内存泄露,它会导致应用程序内存不断消耗和崩溃。我们可以使用 runtime/pprof 包进行检测,并检查函数是否意外保留了对不需要资源的引用。要解决内存泄露,我们需要找到导致泄露的引用,通常通过检查函数代码和查找全局变
golang函数内存泄露检测与解决
2024-04-23

C++内存泄漏的检测与实现详细流程

内存泄漏(memoryleak)是指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费
2022-11-13

PHP应用程序中的内存泄露:原因、检测和解决

php 内存泄露是指应用程序分配内存后未能释放,导致服务器可用内存减少和性能下降。原因包括循环引用、全局变量、静态变量和扩展。检测方法有 xdebug、valgrind 和 phpunit mock objects。解决步骤为:识别泄漏源、
PHP应用程序中的内存泄露:原因、检测和解决
2024-05-09

Linux下c++程序内存泄漏检测代码的示例分析

这期内容当中小编将会给大家带来有关如何解决Linux下c++程序内存泄漏检测代码,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Linux下对于程序内存泄漏检测的方法很多,最常用的的莫过于使用valgrin
2023-06-17

android内存泄露:1、LeakCanarys内存泄漏检测库、非静态的内部类错误使用

一、前言 今天来复习一下有关内存泄露的知识,一个是把之前笔记整理一下,如有一些工具版本更新会写一些当下的使用介绍。另外会参考网上比较好的博文进行修正改进一些知识点 二、内存泄露、内存溢出、内存抖动 首先我们必须对内存泄露有一个最简单的了解,
2022-06-06

c++循环引用导致的内存泄露如何解决

在 C++ 中,循环引用(circular reference)是指两个或多个对象相互引用,导致内存泄漏的情况。解决循环引用导致的内存泄漏问题可以采取以下几种方法:1. 使用智能指针(smart pointers):智能指针是 C++ 提供
2023-10-10

详解Android内存泄漏检测与MAT使用

内存泄漏基本概念 内存检测这部分,相关的知识有JVM虚拟机垃圾收集机制,类加载机制,内存模型等。编写没有内存泄漏的程序,对提高程序稳定性,提高用户体验具有重要的意义。因此,学习Java利用java编写程序的时候,要特别注意内存泄漏相关的问题
2022-06-06

C++技术中的内存管理:内存泄漏检测和调试技巧

检测内存泄漏使用 valgrind 等工具检测内存泄漏。利用 ms visual studio memory profiler 识别泄漏。借助 c++++ runtime library 函数(如 _crtdumpmemoryleaks()
C++技术中的内存管理:内存泄漏检测和调试技巧
2024-05-08

Java语言中的内存泄露代码详解

Java的一个重要特性就是通过垃圾收集器(GC)自动管理内存的回收,而不需要程序员自己来释放内存。理论上Java中所有不会再被利用的对象所占用的内存,都可以被GC回收,但是Java也存在内存泄露,但它的表现与C++不同。JAVA中的内存管理
2023-05-30

Python实现内存泄露排查的示例详解

一般在python代码块的调试过程中会使用memory-profiler、filprofiler、objgraph等三种方式进行辅助分析,今天这里主要介绍使用objgraph对象提供的函数接口来进行内存泄露的分析,感兴趣的可以了解一下
2023-01-28

C++技术中的内存管理:详解内存泄漏的预防措施

c++++ 中的内存泄漏可以通过采取以下措施防止:了解指针、采用智能指针(如 unique_ptr、shared_ptr、weak_ptr)、谨慎使用裸指针、查找和修复内存泄漏(使用内存分析器、调试器、分析器),并通过实际案例展示如何使用
C++技术中的内存管理:详解内存泄漏的预防措施
2024-05-07

C/C++程序调试和内存检测的方法是什么

本篇内容主要讲解“C/C++程序调试和内存检测的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C/C++程序调试和内存检测的方法是什么”吧!1、常用的调试技巧(1)代码检查,重新阅读程
2023-06-05

c语言内存泄漏的解决方法是什么

在C语言中,内存泄漏是指在动态内存分配后,没有释放该内存导致内存空间无法被再次使用的情况。解决内存泄漏的方法可以包括以下几个方面:1. 显式释放内存:在动态内存分配后,在不再需要使用该内存时,使用free()函数将其释放。这需要开发者自己负
2023-09-27

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录