21.6 常见问题及解答
程序员在编写程序时不可避免地都会犯一些常见内存错误,这种现象是很常见的,尤其是初学者。因为编译器在编译你的程序时是不能自动检测出这些内存错误的,而只能在程序运行的时候才能捕获到。所以在编写应用程序时,一定要注意进行合理的内存分配、使用、释放等。一些常见的内存错误,大致可以分成5类,列举如下:
1.内存分配一定会成功吗?
解答:不一定,初学者通常会犯这种错误,因为没有意识到内存分配会不成功,常常认为一定会申请成功。但是当剩余的内存空间不能满足申请的大小时,就会导致无法获得申请的内存。
2.内存分配成功,但没有进行初始化,可以直接使用吗?
解答:这是很危险的,内存虽然分配成功了,但是申请的内存中可能存放了任何预想不到的值。因此直接使用这块内存,例如输出,就会得到莫名其妙的结果。如果被保存的值作为地址来解释,就更会指向不知道哪里的内存空间,从而导致更为严重的问题。
3.内存分配成功,也进行了初始化,但为什么有时会提示操作越界?
解答:这类错误,常常会出现在对指针和数组的操作上。例如,声明了一个数组并初始化后,在一个for循环中对其中的数组元素进行遍历或赋值时,如果循环次数多于数组的大小,就会造成数组下标越界的内存错误发生。
4.内存不使用后,是否必须释放?
解答:在堆上用malloc()和new申请的动态内存,在使用后,没有进行释放,这会造成系统内存碎片或丢失。特别要注意在程序中用new申请的内存区域,要用delete来释放。用malloc()申请的内存,一定要用free来释放。它们必须配对,例如new申请的内存,不要用free()来释放。用malloc()申请的内存,也不能用delete来释放。一般来说,没有释放的内存,在程序运行结束时,操作系统可能会将那些在程序运行时没有释放的堆内存块进行回收。但有很多例外,如丢失内存过多、程序崩溃等,都会造成内存耗尽。所以在使用内存后,一定要释放内存,从而减少这类错误的发生。
5.可以使用释放后的内存吗?
解答:不可以,这类错误多见于指针的使用。当使用free()或delete释放内存后,却没有将指针设置为NULL。这将导致该指针将仍然指向该内存块,因为释放操作仅仅是告诉系统这块内存可以再分配了,并没有对指针地址清零。这就导致"野指针"的产生,即该指针指向了某个内存块,但这块内存却没有在系统内登记为被分配。如果将该内存块分配给其他变量,则当再次用原指针访问这个内存块时,将破坏新变量的内容。
【责任编辑:
云霞 TEL:(010)68476606】