📄 book_text13.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0063)http://www1.ustc.edu.cn/personal/csli/insidec++/book_text13.htm -->
<HTML><HEAD><TITLE>Visual C++</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.2995" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId><LINK
href="book_text13.files/style.css" type=text/css rel=stylesheet></HEAD>
<BODY bgColor=#f7fbff leftMargin=0 topMargin=0>
<TABLE height="100%" cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="3%" background=book_text13.files/page_side.gif
height="100%"> </TD>
<TD vAlign=top align=middle width="97%">
<P
style="mso-line-height-alt: 1.3pt; tab-stops: right dotted 402.1pt"><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt"></O:P></SPAN></P>
<TABLE height=23 width="99%" border=0>
<TBODY>
<TR>
<TD width="2%" height=29></TD>
<TD width="95%" height=29><PRE><A name=_Toc419881649><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: Times New Roman; mso-bookmark: _Toc419740467">四、<SPAN lang=EN-US>VC程序调试</SPAN></SPAN></A></PRE></TD>
<TD width="3%" height=29></TD></TR>
<TR>
<TD width="2%" height=15></TD>
<TD width="95%" height=15>
<H2 style="mso-line-height-alt: 1.3pt"><A name=_Toc419881660><SPAN
lang=EN-US
style="FONT-SIZE: 18pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: Arial; mso-bookmark: _Toc419740478">3
内存漏洞的检查</SPAN></A><SPAN lang=EN-US
style="FONT-SIZE: 18pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: Arial"><O:P>
</O:P></SPAN></H2>
<P class=MsoNormal
style="TEXT-INDENT: 20pt; mso-line-height-alt: 1.3pt"><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'Times New Roman'">也许你已经知道,在<SPAN
lang=EN-US>C++和C语言中指针问题也就是内存申请与释放是一个令人头疼的事情,假如你申请了内存,但没有释放,并且你的程序需要长时间地运行,那么,系统的资源将逐渐减少,当系统的资源全部被用完时,系统将会崩溃。所以在开发程序的过程中一定要保证资源的完全释放。下面我们来介绍内存漏洞的检查。<O:P>
</O:P></SPAN></SPAN></P>
<P class=MsoNormal
style="TEXT-INDENT: 20pt; mso-line-height-alt: 1.3pt"><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'Times New Roman'">也许你会问,系统是怎样支持内存漏洞的检查的?其实在你的<SPAN
lang=EN-US>Debug版本中所有的有关内存分配的函数都是被重载过的,具体过程是这样的,当你的程序申请内存时,它首先调用一般的内存分配函数分配一块稍大的内存块。在这一内存块中分为四个小块:Heap
Information, buffer , User memory block,
buffer。第一块为有关堆的信息,比如,申请该内存的地点(文件名,行号),此内存块的类型(如整型,浮点,或某一类的对象)等等。第二块是一个缓冲区,用于截获用户对其申请内存使用越界的情况。第三块是真正给用户的内存,返回的指针也是指向这儿。第四块也是一个缓冲区,作用同第二块。<O:P>
</O:P></SPAN></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 20pt; mso-line-height-alt: 1.3pt"><SPAN
style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">当你申请的内存均被记录在案后,要检查内存漏洞就比较容易了,粗略地说,假如你要检查某一程序段是否有内存漏洞,你只需在这一程序
段的开始要求系统为你做一个内存使用情况的映象,记录下程序开始时的内存使用情况,然后在程序段的末尾再使系统为你做一次内存映象,比较两次映象,以检查是否有没释放的内存,假如有未释放的内存,根据这一块中有关分配情况的信息来告诉用户在那儿申请的内存没释放。<SPAN
lang=EN-US><O:P> </O:P></SPAN></SPAN></P>
<P class=MsoBodyTextIndent style="mso-line-height-alt: 1.3pt"><SPAN
style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">具体地讲检查内存漏洞需要以下几个步骤:<SPAN
lang=EN-US><O:P> </O:P></SPAN></SPAN></P>
<P class=MsoBodyTextIndent
style="MARGIN-LEFT: 48.25pt; TEXT-INDENT: -21.25pt; mso-line-height-alt: 1.3pt; tab-stops: list 21.25pt; mso-list: l9 level1 lfo52"><SPAN
lang=EN-US style="FONT-FAMILY: Wingdings">l<SPAN
style="FONT: 7pt 'Times New Roman'">
</SPAN></SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">在你所检测的程序段的开始处建立一个<SPAN
lang=EN-US>CmemoryState对象,调用其成员函数Checkpoint,以取得当前内存使用情况的快照;<O:P>
</O:P></SPAN></SPAN></P>
<P class=MsoBodyTextIndent
style="MARGIN-LEFT: 48.25pt; TEXT-INDENT: -21.25pt; mso-line-height-alt: 1.3pt; tab-stops: list 21.25pt; mso-list: l9 level1 lfo52"><SPAN
lang=EN-US style="FONT-FAMILY: Wingdings">l<SPAN
style="FONT: 7pt 'Times New Roman'">
</SPAN></SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">在你所检测的程序段的末尾处再建立一个<SPAN
lang=EN-US>CmemoryState 对象,调用其成员函数Checkpoint ,以取得当前内存使用情况的快照;<O:P>
</O:P></SPAN></SPAN></P>
<P class=MsoBodyTextIndent
style="MARGIN-LEFT: 48.25pt; TEXT-INDENT: -21.25pt; mso-line-height-alt: 1.3pt; tab-stops: list 21.25pt; mso-list: l9 level1 lfo52"><SPAN
lang=EN-US style="FONT-FAMILY: Wingdings">l<SPAN
style="FONT: 7pt 'Times New Roman'">
</SPAN></SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">再建立第三个<SPAN
lang=EN-US>CmemoryState
对象,调用其成员函数Difference,把第一个CmemoryState对象和第二个CmemeoryState对象作为其参数.,如果两次内存快照不相同,则该函数返回非零,说明此程序
段中有内存漏洞。下面我们来看一个典型的例子:<O:P> </O:P></SPAN></SPAN></P>
<P class=MsoBodyTextIndent
style="MARGIN-LEFT: 27pt; TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'"> <O:P>
</O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 1cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black">//
Declare the variables needed<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 1cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black">#ifdef
_DEBUG<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1"> </SPAN>CMemoryState
oldMemState, newMemState, diffMemState;<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1">
</SPAN>OldMemState.Checkpoint();<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 1cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black">#endif<O:P>
</O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN>// do your
memory allocations and deallocations...<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1"> </SPAN>CString s = "This is a
frame variable";<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt; mso-outline-level: 1"><SPAN
lang=EN-US
style="BACKGROUND-POSITION: 0% 50%; BACKGROUND-ATTACHMENT: scroll; BACKGROUND-REPEAT: repeat; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #d9d9d9; mso-bidi-font-family: Times New Roman; mso-shading: white; mso-pattern: gray-15 black; mso-spacerun: yes"> </SPAN><SPAN
lang=EN-US
style="FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1"> </SPAN><SPAN
style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 black">//
the next object is a heap object<O:P> </O:P></SPAN></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1"> </SPAN>CPerson* p = new
CPerson( "Smith", "Alan", "581_0215" );<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 1cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black">#ifdef
_DEBUG<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1">
</SPAN>newMemState.Checkpoint();<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1"> </SPAN>if(
diffMemState.Difference( oldMemState, newMemState ) )<O:P>
</O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes"> </SPAN><SPAN
style="mso-tab-count: 1"> </SPAN>{<O:P>
</O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 0cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black"><SPAN
style="mso-spacerun: yes">
</SPAN>TRACE( "Memory leaked!\n" );<O:P> </O:P></SPAN></P>
<P class=MsoBodyTextIndent
style="TEXT-INDENT: 1cm; mso-line-height-alt: 1.3pt"><SPAN
lang=EN-US
style="BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black">}<O:P>
</O:P></SPAN></P><SPAN lang=EN-US
style="FONT-SIZE: 10pt; BACKGROUND: #d9d9d9; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 black; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">#endif</SPAN>
<P> </P></TD>
<TD width="3%" height=15></TD></TR>
<TR>
<TD width="2%" height=1></TD>
<TD vAlign=top width="95%" height=1><PRE></PRE></TD>
<TD width="3%"
height=1></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -