天天看點

C/C++記憶體管理 1. 靜态記憶體 2. 動态記憶體 3.靜态記憶體和動态記憶體的差別 4.記憶體配置設定方式   5.記憶體釋放問題6.常見的記憶體錯誤及對策7.記憶體管理需要遵循的規則8.動态記憶體管理操作

  靜态記憶體是指在程式開始運作時由編譯器配置設定的記憶體,它的配置設定是在程式開始編譯時完成的,不占用CPU資源。程式中的各種變量,在編譯時系統已經為其配置設定了所需的記憶體空間,當該變量在作用域内使用完畢時,系統會自動釋放所占用的記憶體空間。變量的配置設定與釋放,都無須程式員自行考慮。

  eg:基本類型,數組

  使用者無法确定空間大小,或者空間太大,棧上無法配置設定時,會采用動态記憶體配置設定。用malloc或者new申請任意多少的記憶體,程式員自己負責在何時用free或者delete手動釋放記憶體。隻用malloc或new配置設定的記憶體在堆裡。

  (1) 靜态記憶體配置設定在編譯時完成,不占用CPU資源; 動态記憶體配置設定在運作時,配置設定與釋放都占用CPU資源。

  (2) 靜态記憶體在棧(stack)上配置設定; 動态記憶體在堆(heap)上配置設定。

  (3) 動态記憶體配置設定需要指針和引用類型支援,靜态不需要。

  (4) 靜态記憶體配置設定是按計劃配置設定,由編譯器負責; 動态記憶體配置設定是按需配置設定,由程式員負責。

  虛拟記憶體結構:

C/C++記憶體管理 1. 靜态記憶體 2. 動态記憶體 3.靜态記憶體和動态記憶體的差別 4.記憶體配置設定方式   5.記憶體釋放問題6.常見的記憶體錯誤及對策7.記憶體管理需要遵循的規則8.動态記憶體管理操作

注:這裡談的配置設定,都是指在虛拟記憶體中的配置設定。實際的配置設定需要做的是将虛拟位址映射到實體位址(段頁式存儲管理)。

記憶體配置設定方式一共有三種:

  (1)從靜态存儲區域配置設定(全局變量,靜态變量,在虛拟記憶體的資料段)

  記憶體在程式編譯的時候就已經配置設定好,這塊記憶體在程式的整個運作期間都存在,例如,全局變量,靜态變量。

  (2)在棧上建立(局部變量,在虛拟記憶體的棧,屬于靜态記憶體)

  在執行函數時,函數内局部變量的存儲單元都可以在棧上建立,函數執行結束後這些存儲單元自動被釋放。棧記憶體配置設定運算内置于處理器的指令集中,效率很高,但是配置設定的記憶體容量有限。

  (3)在堆上配置設定,亦稱動态記憶體配置設定(malloc或者new申請,在虛拟記憶體的堆裡,即在“空洞”裡,屬于動态記憶體)

  程式在運作的時候用malloc或者new申請任意多少的記憶體,程式員自己負責在何時用free或者delete手動釋放記憶體。動态記憶體的生存期由程式員決定,使用非常靈活,但是問題也多。

  (1)靜态存儲區域以及建立的棧,在函數執行完以後,出棧銷毀,這個過程會自動釋放靜态配置設定的記憶體,不需要程式員手動操作;

  (2)而動态配置設定的記憶體,實際是在堆上,系統沒法自動釋放堆上的記憶體,需要程式員手動寫free或者delete函數來告訴系統需要釋放堆上哪個位置的記憶體;

  (1)記憶體尚未配置設定成功,卻使用了它;

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

  (2)記憶體配置設定雖然成功,但是尚未初始化就引用它;

  錯誤原因:一是沒有初始化的觀念,二是誤以為記憶體的預設初值全為零,導緻引用初值錯誤(如數組)。

  解決辦法:記憶體的預設初值是什麼并沒有統一的标準,盡管有些時候為零值,但是甯可信其有,不可信其無,無論以何種方式建立數組,都要賦初值。

  (3)記憶體配置設定成功并初始化,但是超過了記憶體的邊界;

  這種問題常出現在數組越界,寫程式是要仔細。

  (4)忘記釋放記憶體,造成記憶體洩露;

  含有這種錯誤的函數每次被調用都會丢失一塊記憶體,開始時記憶體充足,看不到錯誤,但終有一次程式死掉,報告記憶體耗盡。

  (1)用malloc 或者 new 申請記憶體之後,應該立即檢查指針值是否為 NULL ,防止使用指針值為NULL的記憶體;

  (2)不要忘記數組和動态記憶體賦初值,防止未被初始化的記憶體作為右值使用;

  (3)避免數組或者指針下标越界,特别要當心“多1”或者“少1”的操作;

  (4)動态記憶體的申請與釋放必須配對,防止記憶體洩露;

  (5)用free或者delete釋放了記憶體之後,立即将指針設定為NULL,防止産生“野指針”。

  8.1動态記憶體配置設定

  (1)malloc的參數size表示配置設定的記憶體空間的大小,機關是位元組Byte。

  (2)calloc的參數nmemb表示配置設定的記憶體空間占的資料項數目,參數size表示一個資料項的大小,機關是位元組Byte。也就是說calloc配置設定的是nmemb X size大小的記憶體空間。

兩者的差別是calloc将初始化所配置設定的記憶體空間,把所有位設定為0。

  (3)調用成功傳回配置設定記憶體的位址,失敗傳回null。

  8.2動态記憶體釋放

  動态記憶體示例:

繼續閱讀