关青苗 蒋争明
Abstract: Memory management in C++ is a big issue for the users who rely on those languages in their project. And memory management two aspects in its domain, first, make it work right; second, make it fast. Every programmer knows it must be listed like this, because code run dizzily fast, but dont work under control, is no use at all. If memory allocated but not released correctly, then memory leak generate. So the defensive programming is a effective method to avoid the error.
Key word:Memory manage, memory leak, defensive programming
一、引言
内存管理的主要内容有两点:1,将内存正确的分配和释放; 2,让计算机能快速的执行内存的分配和释放。我们都知道这个顺序不能颠倒,因为即使程序运行的很快,但是没有正确的分配和释放内存,这个程序对我们也没有多少用处。
二、内存的分配
C++分配内存按分配类型分为三种。
1、全局静态量,在文件的全局变量区定义一整型变量,诸如static int num = 0定义的变量,这种变量在程序的开始运行到结束运行的全部生命周期都存在,而且此变量名在后面程序内不可以重复定义,如果重复定义,编译器会提示错误,将无法通过编译而生成可运行文件。此种分配类型分配给变量的内存位置是全局区。程序的开始运行时,由编译器分配到内存的全局变量区,直到程序结束,变量所使用的内存被编译器释放。
2、局部变量,典型的是在函数或者语句内部定义的变量,比如for(int i=0; i 3、使用运算符new分配的变量,比如:new int[10], 或者malloc (10*sizeof(int)),此种方式分配的内存位置存在一个称为堆区的内存上,注意它和数据结构的堆是不同的,实现方式类似于链表。一般来说,此种分配方式是在要分配的内存无法预知的情况下,它由程序员手动分配,手动释放。如果程序员在使用此类型变量不正确,将导致各种问题的产生。 三、常见错误及对策 1、对上面提到的全局静态变量num,在程序的使用过程中,就是要注意你的每次改变,都是全局性的,所以尽量不要轻易改变它除非你想这么做。如果为了防止程序的其他用户改变你不希望改变的全局变量,你可以在它前面加上const来限定。比如:const int num = 0;这样别的用户在试图改变之,编译器就会给出警告。 2、而使用局部变量的时候,容易出现的错误就是对变量的生存周期不了解产生的错误,在变量的生存期内重复定义了变量。我们可以使用长命名法来命名变量,这样变量重复定义的机会就大大降低,而且变量名在使用过程中,其意义也更加明显。 3、而使用new分配的变量内存,最容易出现的错误是,没有正确的释放。常见的错误比如,使用int *p = new int来分配一组整形的数组;或者使用delete p来释放int *p = new int[10]分配的数组;或者使用delete运算符再次释放已经释放过的内存块,这样会产生无法预料的后果。这样产生的错误,编译器无法帮组我们识别,所以这种错误更加隐蔽,而且在调试的时候更难发现。我们的对策就是可以使用一个对象的计数器,来监视对象的创建和释放,采取一些断言,比如assert函数,来以防止我们错误的调用delete运算符。 四、应用实例 下面我们使用一段代码来说明我们的3.3中的方法,采用的IDE是vs2010,平台是win7 64位Intel机器。 #include "stdio.h" static int counter_for_object = 0; #define NULL 0 class monster { private: int hp; int mp; public: monster():hp(0),mp(0){ counter_for_object ++;} ~monster(){counter_for_object--; } }; int _tmain(int argc, _TCHAR* argv[]) { monster *groupOfMonsters = new monster[10]; delete [] groupOfMonsters; groupOfMonsters = NULL; printf("end of code\n"); return 0; } 如果在打印界面的end of code之前出现的counter_for_object最后不为0,则可判定出内存泄露. 五、结束语 合理的分配内存和释放内存,是程序员的在编写合理的代码时最重要的任务,而采用合理的策略和良好的代码习惯,是我们能保证代码质量的工具。 参考文献 [1] Scott Meyers, Effective C++[M], Addison-Wesley, 1992. [2] 沈被娜,刘祖照. 计算机软件基础(第三版)[M]. 清华大学出版社.2000. (作者单位:广东科技学院)