C++編程:new和delete(C++動態分配和釋放內存)


C++編程:new和delete(C++動態分配和釋放內存)

C++ new和delete(C++動態分配和釋放內存)

數組的長度是預先定義好的,在整個程序中固定不變。C++ 不允許定義元素個數不確定的數組。例如:

<code>int n;int a[n];  //這種定義是不允許的/<code>

但是在實際的編程中,往往會出現所需的內存空間大小取決於實際要處理的數據多少,而實際要處理的數據數量在編程時無法確定的情況。如果總是定義一個儘可能大的數組,又會造成空間浪費。何況,這個“儘可能大”到底應該多大才夠呢?
為了解決上述問題,C++ 提供了一種“動態內存分配”機制,使得程序可以在運行期間,根據實際需要,要求操作系統臨時分配一片內存空間用於存放數據。此種內存分配是在程序運行中進行的,而不是在編譯時就確定的,因此稱為“動態內存分配”。
在 C++ 中,通過 new 運算符來實現動態內存分配。new 運算符的第一種用法如下:

T *p = new T;

其中,T 是任意類型名,p 是類型為 T* 的指針。
這樣的語句會動態分配出一片大小為 sizeof(T) 字節的內存空間,並且將該內存空間的起始地址賦值給 p。例如:

<code>int* p;p = new int;*p = 5;/<code>

第二行動態分配了一片 4 個字節大小的內存空間,而 p 指向這片空間。通過 p 可以讀寫該內存空間。
new 運算符還有第二種用法,用來動態分配一個任意大小的數組:

T *p =new T[N];

其中,T 是任意類型名,p 是類型為 T* 的指針,N 代表“元素個數”,可以是任何值為正整數的表達式,表達式中可以包含變量、函數調用等。這樣的語句動態分配出 N × sizeof(T) 個字節的內存空間,這片空間的起始地址被賦值給 p。例如:

<code>int* pn;int i = 5 ;pn = new int[i*20];pn[0] = 20 ;pn[100] = 30;/<code>

最後一行編譯時沒有問題,但運行時會導致數組越界。因為上面動態分配的數組只有 100 個元素,pn[100] 已經不在動態分配的這片內存區域之內了。
如果要求分配的空間太大,操作系統找不到足夠的內存來滿足,那麼動態內存分配就會失敗,此時程序會拋出異常。關於這一點,將在後續章節中介紹。
程序從操作系統動態分配所得的內存空間在使用完後應該釋放,交還操作系統,以便操作系統將這片內存空間分配給其他程序使用。C++ 提供

delete 運算符,用以釋放動態分配的內存空間。delete 運算符的基本用法如下:

delete p;

p 是指向動態分配的內存的指針。p 必須指向動態分配的內存空間,否則運行時很可能會出錯。例如:

<code>int* p = new int;*p = 5;delete p;delete p;  //本句會導致程序出錯/<code>

上面的第一條 delete 語句正確地釋放了動態分配的 4 個字節內存空間。第二條 delete 語句會導致程序出錯,因為 p 所指向的空間已經釋放,p 不再是指向動態分配的內存空間的指針了。
如果是用 new 的第二種用法分配的內存空間,即動態分配了一個數組,那麼釋放該數組時,應以如下形式使用 delete 運算符:

delete[] p;

p 依然是指向動態分配的內存的指針。例如:

<code>int* p = new int[20];p[0] = 1;delete[] p;/<code>

同樣地,要求被釋放的指針 p 必須是指向動態分配的內存空間的指針,否則會出錯。
如果動態分配了一個數組,但是卻用delete p的方式釋放,沒有用[],則編譯時沒有問題,運行時也一般不會發生錯誤,但實際上會導致動態分配的數組沒有被完全釋放。


牢記,用 new 運算符動態分配的內存空間,一定要用 delete 運算符釋放。否則,即便程序運行結束,這部分內存空間仍然不會被操作系統收回,從而成為被白白浪費掉的內存垃圾。這種現象也稱為“內存洩露”。
如果一個程序不停地進行動態內存分配而總是沒有釋放,那麼可用內存就會被該程序大量消耗,即便該程序結束也不能恢復。這就會導致操作系統運行速度變慢,甚至無法再啟動新的程序。但是,只要重新啟動計算機,這種情況就會消失。
編程時如果進行了動態內存分配,那麼一定要確保其後的每一條執行路徑都能釋放它。
另外還要注意,釋放一個指針,並不會使該指針的值變為 NULL。


C++編程:new和delete(C++動態分配和釋放內存)

通過分享實用的計算機編程語言乾貨,推動中國編程到2025年基本實現普及化,使編程變得全民皆知,最終實現中國編程之崛起,這裡是中國編程2025,感謝大家的支持。


分享到:


相關文章: