一,代码示例
<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> }
<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> }
<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> }
二、如何查找是否有内存泄露
第一步:把下面的代码黏贴到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)!