自己在處理C++內存分配上的一點心得,如果有錯誤,歡迎大家指出。
變量和對象在內存中的分配都是編譯器在編譯程序時安排好的,但同樣帶來了不便,如數組必須大開小用,指針必須指向一個已經存在的變量或對象。動態內存分配解決了這個問題。
C/C++定義了4個內存區間:代碼區,全局數據區,棧區,堆區。定義變量是在編譯程序的時候就進行的靜態存儲分配。所有的動態分配都是在堆區進行的。不過是不能說的這麼絕對的,與編譯器和庫都是有關聯的。函數的參數未必通過堆棧進行分配,這與具體的編譯器都是有關的。而對於內存分配失敗時的返回值也不一定為NULL,很多的編譯器都可以捕獲new操作符拋出的異常。
全局數據區 代碼區 棧區 堆區
data code stack heap
全局變量 函數 局部變量 new,delete申請的空間
靜態數據 函數參數
常量 返回地址
返回數據
堆內存的分配和釋放是重復利用有限的資源的關鍵。
指針變量名 = new 類型名(初始值);
delete 指針名;
new運算符返回的是一個指向所分配類型變量(對象)的指針,而動態創建的對象本身沒有標識符名。new表達式會從堆區分配對象,然後用括號中的值初始化改對象。而從堆區分配對象時,new表達式調用庫操作符new()。例如:
int *pi = new int(0);
注意在內存分配失敗的時候,會返回零值,所以要在動態分配內存的時候對返回的指針進行檢查。
當使用delete操作符時,只是釋放了指針所指向的內存空間,但指針本身沒有撤銷,指針所占用的內存空間並沒有釋放。
char *pc = new char;
*pc = 'a';
int *pi = new int(8);
棧區 堆區
pc a
pi 8
但該函數或程序執行完畢後系統彈棧,pc和pi這兩個變量將消失,但他們指向的堆區的內存不會自動釋放,那麼該內存將不能使用,除非系統重啟。
寫保護的方法
char *pc = new char;
*pc = 'a';
int *pi = new int(8);
if (pc)
{
delete pc;
}
if (pi)
{
delete pi;
}
char *string = new char[20];
if (string == 0)
{
return;
}
/* ... */
delete []string;