關(guān)青苗 蔣爭明
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
一、引言
內(nèi)存管理的主要內(nèi)容有兩點:1,將內(nèi)存正確的分配和釋放; 2,讓計算機能快速的執(zhí)行內(nèi)存的分配和釋放。我們都知道這個順序不能顛倒,因為即使程序運行的很快,但是沒有正確的分配和釋放內(nèi)存,這個程序?qū)ξ覀円矝]有多少用處。
二、內(nèi)存的分配
C++分配內(nèi)存按分配類型分為三種。
1、全局靜態(tài)量,在文件的全局變量區(qū)定義一整型變量,諸如static int num = 0定義的變量,這種變量在程序的開始運行到結(jié)束運行的全部生命周期都存在,而且此變量名在后面程序內(nèi)不可以重復定義,如果重復定義,編譯器會提示錯誤,將無法通過編譯而生成可運行文件。此種分配類型分配給變量的內(nèi)存位置是全局區(qū)。程序的開始運行時,由編譯器分配到內(nèi)存的全局變量區(qū),直到程序結(jié)束,變量所使用的內(nèi)存被編譯器釋放。
2、局部變量,典型的是在函數(shù)或者語句內(nèi)部定義的變量,比如for(int i=0; i 3、使用運算符new分配的變量,比如:new int[10], 或者malloc (10*sizeof(int)),此種方式分配的內(nèi)存位置存在一個稱為堆區(qū)的內(nèi)存上,注意它和數(shù)據(jù)結(jié)構(gòu)的堆是不同的,實現(xiàn)方式類似于鏈表。一般來說,此種分配方式是在要分配的內(nèi)存無法預(yù)知的情況下,它由程序員手動分配,手動釋放。如果程序員在使用此類型變量不正確,將導致各種問題的產(chǎn)生。 三、常見錯誤及對策 1、對上面提到的全局靜態(tài)變量num,在程序的使用過程中,就是要注意你的每次改變,都是全局性的,所以盡量不要輕易改變它除非你想這么做。如果為了防止程序的其他用戶改變你不希望改變的全局變量,你可以在它前面加上const來限定。比如:const int num = 0;這樣別的用戶在試圖改變之,編譯器就會給出警告。 2、而使用局部變量的時候,容易出現(xiàn)的錯誤就是對變量的生存周期不了解產(chǎn)生的錯誤,在變量的生存期內(nèi)重復定義了變量。我們可以使用長命名法來命名變量,這樣變量重復定義的機會就大大降低,而且變量名在使用過程中,其意義也更加明顯。 3、而使用new分配的變量內(nèi)存,最容易出現(xiàn)的錯誤是,沒有正確的釋放。常見的錯誤比如,使用int *p = new int來分配一組整形的數(shù)組;或者使用delete p來釋放int *p = new int[10]分配的數(shù)組;或者使用delete運算符再次釋放已經(jīng)釋放過的內(nèi)存塊,這樣會產(chǎn)生無法預(yù)料的后果。這樣產(chǎn)生的錯誤,編譯器無法幫組我們識別,所以這種錯誤更加隱蔽,而且在調(diào)試的時候更難發(fā)現(xiàn)。我們的對策就是可以使用一個對象的計數(shù)器,來監(jiān)視對象的創(chuàng)建和釋放,采取一些斷言,比如assert函數(shù),來以防止我們錯誤的調(diào)用delete運算符。 四、應(yīng)用實例 下面我們使用一段代碼來說明我們的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之前出現(xiàn)的counter_for_object最后不為0,則可判定出內(nèi)存泄露. 五、結(jié)束語 合理的分配內(nèi)存和釋放內(nèi)存,是程序員的在編寫合理的代碼時最重要的任務(wù),而采用合理的策略和良好的代碼習慣,是我們能保證代碼質(zhì)量的工具。 參考文獻 [1] Scott Meyers, Effective C++[M], Addison-Wesley, 1992. [2] 沈被娜,劉祖照. 計算機軟件基礎(chǔ)(第三版)[M]. 清華大學出版社.2000. (作者單位:廣東科技學院)