valgrind 检查内存泄漏

2024-02-06 13:32
文章标签 内存 检查 泄漏 valgrind

本文主要是介绍valgrind 检查内存泄漏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

      转载地址:http://blog.csdn.net/abcjennifer/article/details/49227333


内存泄漏是coding中经常容易出现的问题, 而且很难查。 本文中总结了几个常见的内存泄漏问题, 分别举例实现, 并列出用代码分析工具——valgrind中memcheck检查的结果, 一 一对错误进行排查。

本文围绕工程valgrind-sample进行讲解。 先看下工程结构:


这里写图片描述 

methods类写了几个可能存在内存操作问题的函数, main.cpp调用methods类函数: 


methods.h:

<code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifndef  VALGRIND_METHODS_H </span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#define  VALGRIND_METHODS_H </span><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">sample</span>{</span>           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> printx();          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> access_violation();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> mem_overlap();     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> nonfree();         
}                           
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif  //VALGRIND_METHODS_H</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

main.cpp:

<code class="hljs css has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-id" style="box-sizing: border-box; color: rgb(155, 112, 63);">#include</span> <<span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">iostream</span>>               
<span class="hljs-id" style="box-sizing: border-box; color: rgb(155, 112, 63);">#include</span> "<span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">methods</span><span class="hljs-class" style="box-sizing: border-box; color: rgb(155, 112, 63);">.h</span>"              
<span class="hljs-id" style="box-sizing: border-box; color: rgb(155, 112, 63);">#include</span> <<span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">string</span><span class="hljs-class" style="box-sizing: border-box; color: rgb(155, 112, 63);">.h</span>>               <span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">int</span> <span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">main</span>(<span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">int</span> <span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">argc</span>, <span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">char</span> *<span class="hljs-tag" style="color: rgb(0, 0, 0); box-sizing: border-box;">argv</span><span class="hljs-attr_selector" style="color: rgb(0, 136, 0); box-sizing: border-box;">[]</span>)<span class="hljs-rules" style="box-sizing: border-box;">{ <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">sample</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 102, 102);">:<span class="hljs-function" style="box-sizing: border-box;">printx()</span></span></span>;           <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">sample</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 102, 102);">:<span class="hljs-function" style="box-sizing: border-box;">access_violation()</span></span></span>; <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">sample</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 102, 102);">:<span class="hljs-function" style="box-sizing: border-box;">mem_overlap()</span></span></span>;        <span class="hljs-rule" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">sample</span>:<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 102, 102);">:<span class="hljs-function" style="box-sizing: border-box;">nonfree()</span></span></span>;          
<span class="hljs-rule" style="box-sizing: border-box;">}</span></span>                                 </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

下面分别看这几个函数可能会遇到什么问题。

1. sample::printx()

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> printx(){               <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> x;                   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (x == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)              {                        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"X is zero"</span>); }                        
}                            </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

问题显而易见, 变量赋值前引用, 但C编译器并不会报错。

valgrind ./valgrind-sample:

==17495== Conditional jump or move depends on uninitialised value(s) 
==17495== at 0x400D10: sample::printx() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==17495== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples)


2. sample::access_violation()

<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">void access_violation(){                                          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> len = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>;                                                  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*pt</span> = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*)</span>malloc(len<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*sizeof</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)); <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//problem</span>1: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> freed<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p</span> = pt;                                                  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < len; i++){                                p++;                                                      }                                                             <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>; <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//problem</span>2: heap block overrun                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%d</span>\n"</span>, <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p</span>); <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//problem</span>3: heap block overrun            
}                                                                 </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

问题如code所示, 
line3: 指针pt申请了空间,但是没有释放; 
line8: pt申请了5个int的空间,p经过4次循环(i=3时)已达到最后申请的p[4], 在i=4时p所指向的空间没有申请过; (下面valgrind报告中 Invalid write of size 4) 
line9: 同line8 (下面valgrind报告中 Invalid read of size 4 )

valgrind ./valgrind-sample:

==21058== Invalid write of size 4 
==21058== at 0x400D74: sample::access_violation() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058== Address 0x4b32054 is 0 bytes after a block of size 20 alloc’d 
==21058== at 0x490514E: malloc (vg_replace_malloc.c:195) 
==21058== by 0x400D44: sample::access_violation() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058== 
==21058== Invalid read of size 4 
==21058== at 0x400D7E: sample::access_violation() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058== Address 0x4b32054 is 0 bytes after a block of size 20 alloc’d 
==21058== at 0x490514E: malloc (vg_replace_malloc.c:195) 
==21058== by 0x400D44: sample::access_violation() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==21058==


3. sample::mem_overlap()

<code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> mem_overlap(){                     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>];                       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>; i++){       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>[i] = i;                     }                                   memcpy(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> x[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>] = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abcd"</span>;                 strncpy(x + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, x, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>);               
}                                       </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

问题出在memcpy上, 将str指针位置开始copy 5个char到str+1所指空间,会造成内存覆盖。strncpy也是同理。

valgrind ./valgrind-sample:

==27473== Source and destination overlap in memcpy(0x7feffedc1, 0x7feffedc0, 5) 
==27473== at 0x4907566: memcpy (mc_replace_strmem.c:482) 
==27473== by 0x400DD1: sample::mem_overlap() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==27473== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==27473== 
==27473== Source and destination overlap in strncpy(0x7feffeda5, 0x7feffeda3, 3) 
==27473== at 0x490737B: strncpy (mc_replace_strmem.c:329) 
==27473== by 0x400DFA: sample::mem_overlap() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==27473== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples)


4. sample::nonfree()

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> nonfree(){                                                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* str = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>*)<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">malloc</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>*<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>));                     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* ptr = str;                                               <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span> [] ptr; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem<mismatch>: delete - new; malloc - free</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">free</span>(str); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem<invalid>: release freed memory            </span>ptr[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'a'</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem<invalid>: use released memory          </span>
}                                                                  </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

问题如code所示。 
line 4: 用malloc申请空间的指针用free释放;用new申请的空间用delete释放 (valgrind中Mismatched free() / delete / delete []); 
line 5: 由于ptr=str, ptr已被释放,str无需再释放,此处释放了已经被释放的内存(valgrind中 Invalid free() / delete / delete[]); 
line 6: 用到了已经被释放的内存(valgrind中Invalid write of size 1);

valgrind ./valgrind-sample:

==29210== Mismatched free() / delete / delete [] 
==29210== at 0x4906510: operator delete (vg_replace_malloc.c:368) 
==29210== by 0x400E2B: sample::nonfree() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== Address 0x4b32040 is 0 bytes inside a block of size 5 alloc’d 
==29210== at 0x490514E: malloc (vg_replace_malloc.c:195) 
==29210== by 0x400E0F: sample::nonfree() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== 
==29210== Invalid free() / delete / delete[] 
==29210== at 0x4905E72: free (vg_replace_malloc.c:325) 
==29210== by 0x400E34: sample::nonfree() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== Address 0x4b32040 is 0 bytes inside a block of size 5 free’d 
==29210== at 0x4906510: operator delete (vg_replace_malloc.c:368) 
==29210== by 0x400E2B: sample::nonfree() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== 
==29210== Invalid write of size 1 
==29210== at 0x400E3C: sample::nonfree() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== Address 0x4b32041 is 1 bytes inside a block of size 5 free’d 
==29210== at 0x4906510: operator delete
 (vg_replace_malloc.c:368) 
==29210== by 0x400E2B: sample::nonfree() (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples) 
==29210== by 0x400B4B: main (in /home/zhangruiqing01/disk2/study/code/valgrind-samples/valgrind-samples)



最后,整个methods.cpp文件如下:

methods.cpp:

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream>                                                         </span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h>                                                          </span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <string.h>                                                         </span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "methods.h"                                                        </span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> sample{                                                           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> printx(){                                                          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> x;                                                              <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (x == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)                                                         {                                                                   <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"X is zero"</span>);                                            }                                                                   }                                                                       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> access_violation(){                                                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> len = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>;                                                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *pt = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>*)<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">malloc</span>(len*<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem1: not freed      </span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *p = pt;                                                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < len; i++){                                      p++;                                                            }                                                                   *p = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem2: heap block overrun                              </span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%d\n"</span>, *p); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem3: heap block overrun                  </span>}                                                                       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> mem_overlap(){                                                     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> str[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>];                                                       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>; i++){                                       str[i] = i;                                                     }                                                                   <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memcpy</span>(str + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, str, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>);                                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> x[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>] = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abcd"</span>;                                                 <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strncpy</span>(x + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, x, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>);                                               }                                                                       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> nonfree(){                                                         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* str = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>*)<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">malloc</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>*<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>));                          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* ptr = str;                                                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span> [] ptr; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem<mismatch>: delete - new; malloc - free     </span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">free</span>(str); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem<invalid>: release freed memory                 </span>ptr[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'a'</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//problem<invalid>: use released memory               </span>}                                                                       
}          </code>


这篇关于valgrind 检查内存泄漏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/684472

相关文章

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

JVM内存调优原则及几种JVM内存调优方法

JVM内存调优原则及几种JVM内存调优方法 1、堆大小设置。 2、回收器选择。   1、在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。   2、对JVM内存的系统级的调优主要的目的是减少

JVM 常见异常及内存诊断

栈内存溢出 栈内存大小设置:-Xss size 默认除了window以外的所有操作系统默认情况大小为 1MB,window 的默认大小依赖于虚拟机内存。 栈帧过多导致栈内存溢出 下述示例代码,由于递归深度没有限制且没有设置出口,每次方法的调用都会产生一个栈帧导致了创建的栈帧过多,而导致内存溢出(StackOverflowError)。 示例代码: 运行结果: 栈帧过大导致栈内存

理解java虚拟机内存收集

学习《深入理解Java虚拟机》时个人的理解笔记 1、为什么要去了解垃圾收集和内存回收技术? 当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些“自动化”的技术实施必要的监控和调节。 2、“哲学三问”内存收集 what?when?how? 那些内存需要回收?什么时候回收?如何回收? 这是一个整体的问题,确定了什么状态的内存可以

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

NGINX轻松管理10万长连接 --- 基于2GB内存的CentOS 6.5 x86-64

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=190176&id=4234854 一 前言 当管理大量连接时,特别是只有少量活跃连接,NGINX有比较好的CPU和RAM利用率,如今是多终端保持在线的时代,更能让NGINX发挥这个优点。本文做一个简单测试,NGINX在一个普通PC虚拟机上维护100k的HTTP

PHP原理之内存管理中难懂的几个点

PHP的内存管理, 分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理. 而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等. 另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法. 而在我们

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

PHP内存泄漏问题解析

内存泄漏 内存泄漏指的是在程序运行过程中申请了内存,但是在使用完成后没有及时释放的现象, 对于普通运行时间较短的程序来说可能问题不会那么明显,但是对于长时间运行的程序, 比如Web服务器,后台进程等就比较明显了,随着系统运行占用的内存会持续上升, 可能会因为占用内存过高而崩溃,或被系统杀掉 PHP的内存泄漏 PHP属于高级语言,语言级别并没有内存的概念,在使用过程中完全不需要主动申请或释放内

C++学习笔记----6、内存管理(四)---- 通常的内存陷阱(2)

3、Windows环境下使用Visual C++发现并修复内存渗露         内存渗露很难跟踪是因为你无法很容易地看着内存并且看到什么对象处于使用中,一开始在哪儿分配的内存。然而,是有程序可以为你做到这一点的。内存渗露检测工具有昂贵的专业软件包,也有免费下载的工具。如果你是在Microsoft Visual C++环境下工作,它的排错工具库有内建的对于内存渗露检测的支持。该内存检测默认没有