VS内存泄漏检查 tcy
发布日期:2021-06-29 14:44:10 浏览次数:3 分类:技术文章

本文共 4578 字,大约阅读时间需要 15 分钟。

VS内存泄漏检查    2020/3/151.1.说明:	VS调试器和C运行时(CRT)库为我们提供了检测和识别内存泄漏的有效方法1.2.原理:    内存分配要通过CRT在运行时实现,只要在分配内存和释放内存时分别做好记录,    程序结束时对比分配内存和释放内存的记录就可以确定是不是有内存泄漏。1.3.vs中启用内存检测:步骤1:程序开头包含: (注意顺序)#define _CRTDBG_MAP_ALLOC//将CRT堆函数的基版本映射到对应的“Debug”版本#include 
#include
//将malloc,free等映射到调试版本(跟踪内存分配和释放)步骤2:程序尾部包括_CrtDumpMemoryLeaks();//来转储内存泄漏信息步骤3:运行程序(实例1):结果显示 Dumping objects -> {154} normal block at 0x00F26078, 100 bytes long. 步骤4:在程序运行第一句添加:_CrtSetBreakAlloc(154);//产生中断(154要根据实际填写) a)运行程序(实例2)中断 b)在VS下的--自动窗口--调用堆栈:查看输出 > test.exe!GetMemory(char * p, int num) 行 37 C++ 说明源程序的37有问题注意: 并不是说有normal block一定就有内存泄漏,当有全局变量时,全局变量释放示在main函数退出后, 所以在main函数最后_CrtDumpMemoryLeaks()会认为全局申请内存没释放,造成内存泄漏假象。规避: 通常把全局变量声明成指针;int *pInt=new int;...;delete pInt;然后再调用_CrtDumpMemoryLeaks()2.实例:实例1:#define _CRTDBG_MAP_ALLOC#include
#include
#include
using namespace std;_CrtMemState s1, s2, s3;//CRT 库结构类型,可用它存储内存状态的快照void GetMemory(char *p, int num){ p = (char*)malloc(sizeof(char) * num);}int main(int argc, char** argv){ // _CrtSetBreakAlloc(154); _CrtMemCheckpoint(&s1);//用当前内存状态的快照填充此结构 char *str = NULL; GetMemory(str, 100); _CrtMemCheckpoint(&s2); if (_CrtMemDifference(&s3, &s1, &s2))//比较两内存状态(s1和s2)生成这两个状态之间差异的结果(s3) _CrtMemDumpStatistics(&s3);//向_CrtMemDumpStatistics传递_CrtMemState结构,可在任意点转储该结构内容 cout << "Memory leak test!" << endl; _CrtDumpMemoryLeaks();//检查、定位内存泄漏此方法必须在debug模式下进行 return 0;}//当在调试器下运行程序时,_CrtDumpMemoryLeaks 将在“输出”窗口中显示内存泄漏信息。 //内存泄漏信息如下所示:/*0 bytes in 0 Free Blocks.100 bytes in 1 Normal Blocks.0 bytes in 0 CRT Blocks.0 bytes in 0 Ignore Blocks.0 bytes in 0 Client Blocks.Largest number used : 0 bytes.Total allocations : 100 bytes.Detected memory leaks!Dumping objects ->{154} normal block at 0x00F26078, 100 bytes long.Data : < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.*/说明: //{ 154 } normal block at 0x00F26078, 100 bytes long.//被{}包围154就是内存泄漏定位值,100 bytes long就是说这个地方有100比特内存没有释放。实例2:...//同上int main(int argc, char** argv){ _CrtSetBreakAlloc(154);//首行 ...//同上}
实例3:#include
#ifdef _DEBUG#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)#endifint main(){ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); _CrtSetBreakAlloc(147);// int *temp = new int(100); _CrtDumpMemoryLeaks();//或将此放到程序的最后}/*Detected memory leaks!Dumping objects ->c:\users\administrator\source\repos\test\test\test.cpp(28) : {77} normal block at 0x012F6248, 4 bytes long. Data : < d > 64 00 00 00 Object dump complete. Detected memory leaks! Dumping objects -> c : \users\administrator\source\repos\test\test\test.cpp(28) : {77} normal block at 0x012F6248, 4 bytes long. Data : < d > 64 00 00 00*/
实例4: #include
//查看内存是否泄漏#ifdef _DEBUG#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)#endif class _pManageStudent{ friend class Student; int *_p; size_t _pTotal; _pManageStudent(int *p) :_p(p), _pTotal(1) {} ~_pManageStudent(){cout << "~_pManageStudent():" << *_p << endl;delete _p; }}; class Student{public: Student(int *p, int i):ptr(new _pManageStudent(p)), size(i) {} Student(const Student &obj) :ptr(obj.ptr), size(obj.size) { ++(ptr->_pTotal); cout << "Student(const Student &obj):" << ptr->_pTotal << endl; } Student& operator=(const Student &obj); ~Student(); int getPtr()const; int getSize() const; void setPtr(int *p); void setSize(int i);private: _pManageStudent *ptr; int size;}; Student& Student::operator=(const Student &obj){ ++(obj.ptr->_pTotal); if (--(ptr->_pTotal) == 0){delete ptr;} ptr = obj.ptr; size = obj.size; return *this;} Student::~Student(){ cout << "~Student():" << ptr->_pTotal << endl; if (--(ptr->_pTotal) == 0) delete ptr; } int Student::getPtr() const {return *ptr->_p;}int Student::getSize() const{return size;}void Student::setPtr(int *p){ptr->_p = p;}void Student::setSize(int Size){size = Size;} < /FONT > int main(){_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);_CrtSetBreakAlloc(147); //查看内存是否泄漏 int *p = new int(100); Student ptr(p, 22); printf("%d;%d;\n", ptr.getPtr(), ptr.getSize()); Student ptr2(ptr); printf("%d;%d;\n", ptr.getPtr(), ptr.getSize()); cout << (p != NULL )<< endl; //delete temp; return 0; } 输出://100; 22; //Student(const Student &obj) :2//100; 22; //1//~Student() :2 //~Student() : 1//~_pManageStudent() : 100

 

 

 

转载地址:https://chunyou.blog.csdn.net/article/details/104877765 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:C/C++动态内存tcy
下一篇:C/C++字符串数字相互转换

发表评论

最新留言

不错!
[***.144.177.141]2024年04月09日 03时11分06秒