在我们随手编制的VC程序中,普遍存在着会发生内存泄漏的隐患,有些问题程序的痼疾症状是在处理数据量激增时陷入瘫痪,更糟的要发现内存泄漏并不容易。首先,我们要明确VC中内存泄漏的含义:简单说就是一个程序申请得到了一段内存却没有及时释放。比如用new在堆中分配了一个对象或对象组却并没有调用delete操作。灵活的指针技术使内存泄漏的原因变得复杂化,比如改变了保存在一变量中的指针的值后未能删除指针所指向的内存区;当内存泄漏是来自一个带有指针类型成员变量的类时会更加困难,因为当调用分配指针时并没有复制构造函数/析构函数或运算符。
为了防止发生内存泄漏这样棘手的故障,在VC编程时应当注意遵循几个规范:其一,如果一个类包含有指针并且分配了指针值,那么就需要构造相应的析构函数以删除该指针;其二,如果一个函数分配了一块内存并把该内存块返回给调用它的函数使用,那么它返回的必须是一个指针而非一个引用,因为引用不能被程序删除;其三,即使一个函数分配了一段内存并在同一函数的稍后部分删除了该内存段,也要尽可能将内存块分配到堆栈中;最后,就是决不要试图改变一个指针值,除非已经删除指针所指的对象或通过数组指向了该指针所指向的内存,而且也不要对new返回的指针进行加1运算。
每当编写VC程序时,我们都会处于一个琳琅满目的集成开发环境(IDE)中,现实的真相是我们很多人在这里编程多年,对开发环境了解并不全面和细微。记得王朔的小说中有句话说"穿了多年的外套在不穿时才发现它原来还有一个兜!"。我们在安装VC时,得到的IDE即Developer Studio, VC其实是Developer Studio下激活的一个组件而已,比如微软的VJ++也是基于Developer Studio。很少有技术书籍会一一介绍Developer Studio界面元素,也许聪明的程序员轻易就能识别其含义,全部猜对界面图符的含义并非易事。可是它们对我们了解开发信息很重要,也与调试程序有关联。
在Developer Studio下会生成多个文件去保存项目的所有信息:一个是以.DSW为扩展名的项目工作区文件,它包含项目中所有文件的名称、文件所在目录、编译器和连接器的选项以及项目工作的其它信息;以.DSP为扩展名的也是项目记录文件,.OPT是工作区选项文件,它包含Developer Studio的所有个人设置 - 包括颜色、字体、工具栏、哪个文件被打开以及MDI窗口如何被定位和最新调试中的断点等。在打开项目工作区文件时其它文件随即会自动打开。在Developer Studio下可以按类查看代码,其中的ClassView显示了应用程序中所有的类,每个类下显示了成员函数和数据成员,在成员函数旁有粉红图标,数据成员旁是蓝绿色图标,保护类成员的图标旁有一枚钥匙,私有类成员则有一个挂锁图标。
当然,在开发环境下最主要的工作是输入编辑程序源代码,源代码会显示"语法着色"。在缺省情况下,代码为黑色,夹以绿色的注释和蓝色的关键字(指VC所保留的public、private、new和int等等)。--这些地球人都知道,但是为了调试需要,我们还可以指定颜色去显示字符串、数字和运算符。定义方法是通过Tools菜单下的Options对话框中的Format选项卡设置。
在Developer Studio提供的诸多菜单项中,我们往往对少数菜单避而不用,因为不了解它们的作用唯恐好奇心会造成乱子;还有多个菜单项都可以达到目的,至于它们之间的微小差别则不甚了了。比如在编译和调试时常用到Build菜单组,它具有和应用程序编译、运行调试相关的多项操作:其中的Compile菜单会编译当前的聚焦文件;Build菜单会编译和链接所有在项目中修改的文件;Build All会编译链接项目中所有文件,包括最近编译后没有修改过的文件;Batch Build用于包含有Debug和Release配置的项目;Clean会删除所有的中间和输出文件,因而项目目录下仅包含源文件;Debugger Remote Connection用于远程调试,即在一台机器运行程序而在另一台调试;Set Active Configuration可设置某个配置为激活状态(Debug或Release);Profiler能够识别应用程序的瓶颈,即找到降低程序执行速度的代码和有关模块,为此需要在"工程/设置/Link"下勾选Profiling。
VC中的警告信息是有级别的。在"工程/设置"下的"C/C++"选项卡中的警告级别Warning Level缺省值是3,如果改为更为严格的4级,往往会产生更多的警告类错误。在C/C++选项卡中还提供了代码优化栏Optimizations,在你完成漫漫调试之旅准备正式发布前夕,你应当改动此项,它提供了一些适合建立发行版应用程序的优化设置。
其实,在多年以前,在软件业中针对开发具有一定规模软件项目的情况就出现了软件工程理论,以此来指导软件人员树立团队协作意识,进而保证软件项目的协调性及进度质量等。笔者在从事VC开发中对此很有感触,而且觉得对于每个开发人员自己也应当具备一定的工程素养。比如,我们在开发初期时,应当对所编写的有价值的源代码及时备份,即使有些代码在后续阶段似乎没有用处了也不妨“敝帚自珍”。在VC编程中我经常遇到的问题是,一个不算小的编写了很久的程序,在稍微扩展一点功能时出现了故障,而最挠头的时花了很多时间也无法排故,所幸的是对原来的程序我还有备份,可以重新再来--功能还要加,只是还一种编程思路去实现相同的功能。说实在的,本人在VC开发中,如果要总结“解决了多少问题”,不如说很多时候是采用"游击战"巧妙地"绕过"了一些棘手的问题。--尤其在软件交工处于倒计时的开发后期出现的故障,往往你已经没有时间去找到故障,而是用前一个完好的VC Project去尝试另一条捷径。
查看本文来源