首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在C++代码/项目中查找内存泄漏?

如何在C++代码/项目中查找内存泄漏?
EN

Stack Overflow用户
提问于 2011-06-07 06:09:04
回答 19查看 342.4K关注 0票数 229

我是Windows平台上的C++程序员。我正在使用2008。

我通常会在代码中出现内存泄漏。

通常,我通过检查代码来发现内存泄漏,但是它很麻烦,而且并不总是一个好方法。

因为我买不起付费的内存泄漏检测工具,所以我想让你们提出避免内存泄漏的最佳方法。

  1. 我想知道程序员是如何发现内存泄漏的。
  2. 是否有任何标准或程序应该遵循,以确保程序中没有内存泄漏?
EN

回答 19

Stack Overflow用户

回答已采纳

发布于 2011-12-07 15:28:21

指令

你需要的东西

  • 熟练掌握C++
  • C++编译器
  • 调试器和其他调查软件工具

1

了解操作人员的基本知识。C++运算符new分配堆内存。delete运算符释放堆内存。对于每个new,您都应该使用一个delete,以便释放分配的相同内存:

代码语言:javascript
运行
复制
char* str = new char [30]; // Allocate 30 bytes to house a string.

delete [] str; // Clear those 30 bytes and make str point nowhere.

2

只有在删除的情况下才重新分配内存。在下面的代码中,str获得了第二个分配的新地址。第一个地址不可挽回地丢失,它所指向的30个字节也是如此。现在它们是不可能释放的,而且您有一个内存泄漏:

代码语言:javascript
运行
复制
char* str = new char [30]; // Give str a memory address.

// delete [] str; // Remove the first comment marking in this line to correct.

str = new char [60]; /* Give str another memory address with
                                                    the first one gone forever.*/

delete [] str; // This deletes the 60 bytes, not just the first 30.

3.

注意那些指针分配。每个动态变量(堆上分配的内存)都需要与指针相关联。当动态变量与指针断开关联时,就不可能擦除。同样,这会导致内存泄漏:

代码语言:javascript
运行
复制
char* str1 = new char [30];

char* str2 = new char [40];

strcpy(str1, "Memory leak");

str2 = str1; // Bad! Now the 40 bytes are impossible to free.

delete [] str2; // This deletes the 30 bytes.

delete [] str1; // Possible access violation. What a disaster!

4.

小心本地指针。在函数中声明的指针在堆栈上分配,但它指向的动态变量在堆上分配。如果不删除它,它将在程序退出该函数后保持不变:

代码语言:javascript
运行
复制
void Leak(int x){

char* p = new char [x];

// delete [] p; // Remove the first comment marking to correct.

}

5

注意“删除”后的方括号。使用delete本身释放单个对象。使用带有方括号的delete []释放堆数组。不要做这种事:

代码语言:javascript
运行
复制
char* one = new char;

delete [] one; // Wrong

char* many = new char [30];

delete many; // Wrong!

6

如果泄漏还允许的话-我通常使用删除器查找它(请在这里查看:http://deleaker.com)。

票数 341
EN

Stack Overflow用户

发布于 2011-06-07 06:13:15

您可以在代码中使用一些技术来检测内存泄漏。最常见和最简单的检测方法是,定义宏(例如DEBUG_NEW )并使用它,以及预定义的宏(如__FILE____LINE__ )来定位代码中的内存泄漏。这些预定义的宏告诉您内存泄漏的文件和行数。

DEBUG_NEW只是一个宏,通常定义为:

代码语言:javascript
运行
复制
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

这样,无论您在何处使用new,它都可以跟踪文件和行号,这些文件和行号可用于查找程序中的内存泄漏。

__FILE____LINE__是计算文件名和行号的预定义宏,它们分别是您使用它们的位置!

请阅读下面的文章,其中解释了如何将DEBUG_NEW与其他有趣的宏一起使用,非常漂亮:

跨平台内存泄漏检测器

来自维基百科

Debug_new是指C++中的一种技术,用于重载和/或重新定义操作符new和运算符delete,以便拦截内存分配和去分配调用,从而调试内存使用程序。它通常涉及定义一个名为new(_FILE_,_LINE_)的宏,并使其成为类似于的东西,用于记录分配中的文件/行信息。 Microsoft Visual C++在其Microsoft类中使用这种技术。有一些方法可以扩展此方法,以避免使用宏重新定义,同时仍然能够在某些平台上显示文件/行信息。这种方法有许多固有的局限性。它只适用于C++,不能捕获C函数(如malloc )的内存泄漏。但是,与一些更完整的内存调试器解决方案相比,它可以非常简单地使用,而且速度也非常快。

票数 36
EN

Stack Overflow用户

发布于 2016-06-06 15:45:42

运行“增值”罐的

1) 帮助识别内存泄漏()--显示您有多少内存泄漏,并指出分配泄漏内存的代码行。

2) 指出了释放内存的错误尝试(例如delete的错误调用)

关于使用“的说明

1)获取这里

2)使用-g标志编译代码

3)在shell中运行:

代码语言:javascript
运行
复制
valgrind --leak-check=yes myprog arg1 arg2

其中"myprog“是您编译的程序和arg1arg2是您的程序的论点。

4)结果是对malloc/new的调用列表,这些调用没有后续的空闲删除调用。

例如,

代码语言:javascript
运行
复制
==4230==    at 0x1B977DD0: malloc (vg_replace_malloc.c:136)

==4230==    by 0x804990F: main (example.c:6)

告诉您在哪一行调用了malloc (未释放)。

正如其他人所指出的,确保每个new/malloc调用都有一个后续的delete/free调用。

票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6261201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档