除调试工具外,Visual C++还提供了两个很有用的宏函数:TRACE()和ASSERT(),它们常常配合调试使用。TRACE的函数原型为:
TRACE(exp )
TRACE(DWORD category, UINT level, LPCSTR lpszFormat, ... )
ATLTRACE2( exp );
ATLTRACE2(
DWORD category,
UINT level,
LPCSTR lpszFormat,
...
);
TRACE()的效果如图2-23所示。可以看到,TRACE()和printf()的使用方式一样。只不过它的输出不是标准输出设备,而是Visual C++的输出窗口。
<DIV> TRACE()语句输出调试信息至输出窗口 </DIV> |
<DIV> TRACE()语句 </DIV> |
图2-23 使用TRACE()输出调试信息
断言ASSERT用于检查一些“不应该”发生的情况。ASSERT的函数原型如下:
ASSERT(
booleanExpression
)
ASSERT的含义就是“条件booleanExpression必须得满足”(即条件bExpression为true),如:
int a = 3, b = 4;
int c = a + b;
ASSERT(c == 7);
“条件booleanExpression一定得满足”,那么,“不满足”会怎么样?当ASSERT 断言的条件bExpression为false的时候,Visual C++将会给出红色的警告,如图2-24所示。
图2-24 ASSERT窗口
此时,我们可以单击【终止】按钮以终止该程序;单击【忽略】按钮以继续执行后面的语句;如果要跟踪进去查看错误源,则单击【重试】按钮,这样的话程序将会转至发生ASSERT错误的代码行,并暂停程序执行。
提示
TRACE()和ASSERT()宏只有在调试版本(即_DEBUG宏被定义)时才能奏效。对于Release版本,TRACE()和ASSERT()宏没有任何作用。
_DEBUG宏,也是微软在开发Visual C++环境(即微软所开发的提供我们使用的一些.h和.CPP文件)时所使用的一个开关,类似于宏UNICODE。所谓调试版本,即在源代码中保持_DEBUG宏,从而选择了Visual C++环境中的调试代码;Release版本,即在源代码中取消(undef)_DEBUG宏作用,从而不选择了Visual C++环境中的调试代码。
此外,Visual C++调试器提供了对内存泄漏的检测功能,考察如下一段包含内存泄漏的C++程序:
【程序 2‑2】一段包含内存泄漏的程序
01 #include "stdafx.h" 02
03 int main() 04 { 05 int * ip = new int; 06 return 0; 07 } |
运行如上包含内存泄漏的程序时,可以看到Visual C++的输出窗口产生如下内容,如图2-25所示。
图2-25 Visual C++中内嵌的内存泄漏检测
其明确地输出内存泄漏的信息:
Detected memory leaks!
Dumping objects ->
{80} normal block at 0x003E2A20, 4 bytes long.
Data: < > CD CD CD CD
Object dump complete.
光盘导读
该项目对应于光盘中的目录“\ch02\MemleakTest”。
虽然通过调试窗口,我们可以很明显地看到内存泄漏的所在(一个new出来的整形变量所占用的4个字节没有释放),但是针对稍微庞大一点的项目而言,如上的这种信息似乎也只能起到提醒的作用,程序员很难定位到程序的出错点。这就需要更高的内存处理和调试技巧,第3.5节“智能指针(smart pointer)”将会介绍如何采用智能指针避免程序中的内存泄漏问题。
MSDN参考
欲在MSDN中查看相关信息,可使用关键字:“MFC,内存管理”。
参考: