当前位置:首页 > 操作系统 > Windows

[VS] 使用Visual Studio查找和定位内存泄露 @Windows

一,代码示例

                <span> 1</span> #include <stdio.h>
<span> 2</span><span> 3</span><span>void</span>*<span> memleak1();
</span><span> 4</span><span>void</span>*<span> memleak2();
</span><span> 5</span><span> 6</span><span>int</span><span> main()
</span><span> 7</span><span>{
</span><span> 8</span><span>void</span> *p1 =<span> memleak1();
</span><span> 9</span><span>void</span> *p2 =<span> memleak2();
</span><span>10</span><span>11</span>     printf(<span>"</span><span>p1=%p, p2=%pn</span><span>"</span><span>, p1, p2);
</span><span>12</span><span>13</span><span>return</span><span>0</span><span>;
</span><span>14</span> }
main.c
                <span>1</span>
                <span>/*</span>
                <span> memleak1.c </span>
                <span>*/</span>
                <span>2</span> #include <stdlib.h>
<span>3</span><span>4</span><span>void</span>*<span> memleak1()
</span><span>5</span><span>{
</span><span>6</span><span>return</span> malloc(<span>1</span><span>);
</span><span>7</span> }
memleak1.c
                <span>1</span>
                <span>/*</span>
                <span> memleak2.c </span>
                <span>*/</span>
                <span>2</span> #include <stdlib.h>
<span>3</span><span>4</span><span>void</span>*<span> memleak2()
</span><span>5</span><span>{
</span><span>6</span><span>return</span> malloc(<span>2</span><span>);
</span><span>7</span> }
memleak2.c

二、如何查找是否有内存泄露

第一步:把下面的代码黏贴到main()函数所在的源文件:

            <span>#ifdef _DEBUG
 
#include </span><stdlib.h><span>
#include </span><crtdbg.h><span>
 
#ifndef DEBUG_NEW
</span><span>#define</span> DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
<span>#define</span> new DEBUG_NEW
<span>#endif</span><span>#endif</span>

第二步,把下面的代码黏贴到main()函数的开头:

            <span>char</span> *<span>b;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF </span>|<span> _CRTDBG_LEAK_CHECK_DF);
b </span>= (<span>char</span>*) malloc(<span>20</span>);

最后,重新编译debug模式并运行vs工程,在输出窗口就可以看到这样的提示:

Detected memory leaks!<span>
Dumping objects </span>-><span>
{</span><span>56</span>} normal block at <span>0x00171580</span>, <span>20</span> bytes <span>long</span><span>.
 Data: </span><                ><span> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
{</span><span>55</span>} normal block at <span>0x00171540</span>, <span>2</span> bytes <span>long</span><span>.
 Data: </span><  ><span> CD CD 
{</span><span>54</span>} normal block at <span>0x00171500</span>, <span>1</span> bytes <span>long</span><span>.
 Data: </span>< ><span> CD 
Object dump complete.</span>

这里,我们就可以看到内存泄露的位置和泄露的数量。

三、如何定位内存泄露的位置

第一步,添加预定义宏(preprocessor marco)到vs工程中:

_CRTDBG_MAP_ALLOC=<span>1</span>

这时候重新编译并运行工程,我们会得到这样的输出,说明我们已经定位20个byte的泄露来自于main.c里的第25行,正是我们加入的测试内存泄露的代码。但是我们还是没有定位到另外两处内存泄露。

Detected memory leaks!<span>
Dumping objects </span>-><span>
c:usersjxiondocumentsgithubmemleakmemleakmain.c(</span><span>25</span>) : {<span>56</span>} normal block at <span>0x00401580</span>, <span>20</span> bytes <span>long</span><span>.
 Data: </span><                ><span> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
{</span><span>55</span>} normal block at <span>0x00401540</span>, <span>2</span> bytes <span>long</span><span>.
 Data: </span><  ><span> CD CD 
{</span><span>54</span>} normal block at <span>0x00401500</span>, <span>1</span> bytes <span>long</span><span>.
 Data: </span>< ><span> CD 
Object dump complete.</span>

第二步,在所有我们怀疑有内存泄露的源文件的开始位置,添加下面的代码:

            <span>#ifdef _DEBUG
 
#include </span><stdlib.h><span>
#include </span><crtdbg.h><span>
 
#ifndef DEBUG_NEW
</span><span>#define</span> DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
<span>#define</span> new DEBUG_NEW
<span>#endif</span><span>#endif</span>

这时我们可以定位所有的内存泄露的位置了:

Detected memory leaks!<span>
Dumping objects </span>-><span>
c:usersjxiondocumentsgithubmemleakmemleakmain.c(</span><span>25</span>) : {<span>56</span>} normal block at <span>0x000F1580</span>, <span>20</span> bytes <span>long</span><span>.
 Data: </span><                ><span> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
c:usersjxiondocumentsgithubmemleakmemleakmemleak2.c(</span><span>19</span>) : {<span>55</span>} normal block at <span>0x000F1540</span>, <span>2</span> bytes <span>long</span><span>.
 Data: </span><  ><span> CD CD 
c:usersjxiondocumentsgithubmemleakmemleakmemleak1.c(</span><span>19</span>) : {<span>54</span>} normal block at <span>0x000F1500</span>, <span>1</span> bytes <span>long</span><span>.
 Data: </span>< ><span> CD 
Object dump complete.</span>

四、查找第三方库是否有内存泄露:

调用第三方预编译库(prebuilt)也有可能有内存泄露,但是我们没办法把上面的代码加入到第三方库中重新编译库。我们只能使用间接的方法。例如:打印我们认为可能有内存泄露的第三方函数调用,然后与输出窗口里的内存泄露地址做比较,如上面的例子中,内存泄露位置为:

Detected memory leaks!<span>
Dumping objects </span>-><span>
c:usersjxiondocumentsgithubmemleakmemleakmain.c(</span><span>25</span>) : {<span>56</span>} normal block at <span>0x002D1580</span>, <span>20</span> bytes <span>long</span><span>.
 Data: </span><                ><span> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
{</span><span>55</span>} normal block at <span>0x002D1540</span>, <span>2</span> bytes <span>long</span><span>.
 Data: </span><  ><span> CD CD 
{</span><span>54</span>} normal block at <span>0x002D1500</span>, <span>1</span> bytes <span>long</span><span>.
 Data: </span>< ><span> CD 
Object dump complete.</span>

同时打印的内存分配地址为:

发现了没?两者的地址是一致的,我们同样可以拿这个作为一个定位内存泄露的原则。

 

原文:http://www.cnblogs.com/xjsxjtu/p/3931209.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

相关教程推荐

其他课程推荐