內存使用

在做嵌入式開發過程中,內存問題時時提醒着我們,小心小心又小心的使用者有限的內存。

 

內存分配方式:

1、從靜態區域分配。內存在程序編譯的時候就已經分配好了,這塊內存在程序的整個運行期間都存在。例如全局變量、static變量。

2、在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配的運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。

3、從堆上分配。也稱爲動態分配,程序在運行是調用mallocnew申請任意的內存,程序員自己負責在何時使用freedelete釋放內存。動態內存的生存週期由程序員自己決定,使用靈活!

 

常見的內存使用錯誤已經對策

1、內存分配未成功,卻使用了它。

新手常犯,沒有意識到內存分配會不成功。

常用的解決辦法:在使用內存之前檢查指針是否爲NULL。如果指針p是函數的參數,那麼在函數的入口處用assert(p!=NULL)進行檢查,如果用malloc或new來申請內存,應該用if(p==NULL)或if(p!=NULL)進行防錯處理。

2、內存分配雖然成功,但是尚未初始化就使用。

主要由兩個原因:一是沒有初始化的觀念;二是誤以爲內存的缺省初始值全爲零,導致引用初值錯誤。內存的初始值到底是什麼,我們無法確定,所以,無論用何種方式牀數組或指針,都別忘了賦初值。即使是零值,不可省略,不要嫌麻煩。

3、內存分配成功並已經初始化,但是操作越過了內存的邊界。

例如在使用數組經常發生下標“多1”或“少1”的操作,特別是在for循環語句中,循環的次數很容易搞錯,導致數組操作越界。

4、忘記釋放內存,導致內存泄露。

含有這種錯誤的函數每被調用一次就丟失一塊內存。剛開始時系統的內存不足,你看不到錯誤,中有一次程序突然死掉,系統出現提示:內存不足。動態內存的申請與釋放必須配對,程序中malloc與free的使用一定要相同,否則肯定有錯誤。

5、釋放了內存卻繼續使用它。

A 程序中的對象調用關係過於複雜,實在難以搞清楚某個對象究竟是否已經釋放了內存,此時應該重新設計數據結構,從根本上解決對象管理的混亂局面。

B 函數的return語句寫錯了,注意不要返回“棧內存”的指針或引用,因爲這些內存在函數結束時被自動銷燬了。

C 使用free或delete釋放了內存後,沒有將指針設置爲NULL,導致產生野指針

 

野指針

野指針不是NULL指針,是指向“垃圾”內存的指針,你可能不會用錯NULL指針,因爲if語句很容易就判斷出來,但是野指針是很危險的,if語句對它不起作用。

野指針的成因主要有:

A 指針變量沒有被初始化。任何指針變量在創建時都不會被自動初始化爲NULL指針,它的默認值是隨機的,亂指一氣。所以,指針變量在創建的同時應當被初始化,將指針設置爲NULL,或者指向合法的內存。

                char *p = NULL;

                char *str = (char *)malloc(100);

B 指針P被free或者delete之後,沒有設置爲NULL,讓人誤以爲p是個合法的地址。

 

補充一點,熟悉C++的朋友可能會問,有了malloc/free爲什麼還要new/delete?下面是小弟平時學習過程中遇到的一些答案

前者是C或C++的標準庫函數,而後者是C++的運算符,他們都可以用於申請動態內存和釋放內存。New和delete不是函數而是運算符。

對於非內部數據類型的對象而言,光用malloc和free無法滿足動態對象的要求,對象在創建愛你的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數,由於malloc和free是函數而不是運算符,不在編譯器的控制範圍之內,不能夠把執行構造函數和析構函數的任務強加於他。

既然new和delete的功能完全覆蓋了malloc和free函數,爲什麼C++不把malloc和free淘汰呢?因爲C++程序經常要調用C函數,而C程序只能使用malloc和free函數。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章