C++動態內存分配:new與delete的基礎用法

在C++中,我們經常需要處理數據的存儲問題。有時候,我們可能不知道需要多少內存,或者需要根據程序運行時的情況來動態調整內存大小。這時候,靜態內存分配(比如直接定義變量)就不夠用了,這就需要用到動態內存分配。

爲什麼需要動態內存分配?

我們平時寫代碼時,靜態內存分配(比如 int a;char s[20];)是在編譯時就確定了內存大小,由編譯器自動管理。但如果遇到這樣的場景:需要存儲一組不確定數量的數據(比如用戶輸入的多個數字),或者臨時需要一塊很大的內存,靜態內存就顯得不夠靈活了。

動態內存分配允許我們在運行時根據實際需求向“堆”申請內存,使用完後再手動釋放。堆是一塊獨立的內存區域,大小相對靈活,但需要我們自己負責管理,避免內存泄漏。

動態內存與堆/棧的簡單區別

  • 棧(Stack):由編譯器自動分配和釋放,用於存儲局部變量、函數參數等,內存大小有限且速度快。
  • 堆(Heap):程序運行時動態申請的內存區域,大小靈活但由程序員手動管理,需要顯式釋放。

newdelete 就是用來操作堆內存的核心工具。

new 操作符:在堆上分配內存

要在堆上申請內存,我們使用 new 操作符。它的語法很簡單:

1. 分配單個對象

類型* 指針變量 = new 類型;  // 分配一個該類型的內存空間

例如,分配一個 int 類型的動態變量:

int* p = new int;  // p 指向堆上一個 int 類型的內存空間

此時,p 是一個指針,我們可以通過 *p 訪問或修改這塊內存的值:

*p = 100;  // 將 100 存入 p 指向的內存
cout << "動態變量的值:" << *p << endl;  // 輸出 100

如果需要在分配時初始化內存,可以直接在 new 後加括號傳入初始值:

int* num = new int(20);  // 直接初始化爲 20
cout << "初始化後的變量:" << *num << endl;  // 輸出 20

2. 分配數組

如果需要一組數據(比如數組),可以用 new[] 來分配:

類型* 數組指針 = new 類型[數組大小];  // 分配數組內存

例如,分配一個包含 5 個 int 的動態數組:

int* arr = new int[5];  // arr 指向一個有 5 個 int 的數組

數組元素默認不初始化(值可能是隨機的),如果需要初始化(比如全爲 0),可以寫成:

int* arr = new int[5]();  // 每個元素被初始化爲 0

使用數組時,可以通過下標訪問元素:

for (int i = 0; i < 5; ++i) {
    arr[i] = i * 2;  // 數組賦值:0, 2, 4, 6, 8
}
// 打印數組元素
for (int i = 0; i < 5; ++i) {
    cout << "arr[" << i << "] = " << arr[i] << endl;
}

delete 操作符:釋放堆內存

new 分配的內存不會自動釋放,必須用 deletedelete[] 手動釋放,否則會導致內存泄漏(程序佔用的內存越來越多,最終崩潰)。

1. 釋放單個對象

如果用 new 分配了單個對象,用 delete 釋放:

int* p = new int(100);
// 使用完後釋放內存
delete p;  // p 指向的堆內存被釋放,之後不能再用 *p

2. 釋放數組

如果用 new[] 分配了數組,必須用 delete[] 釋放,否則只會釋放數組第一個元素的內存,導致內存泄漏:

int* arr = new int[5];
// 使用完後釋放數組
delete[] arr;  // 必須用 delete[],不能用 delete!

常見錯誤與注意事項

  1. 忘記釋放內存:用 new 分配後不 delete,會導致內存泄漏。例如:
   int* p = new int(5);
   // 使用 p...
   // 忘記寫 delete p; 這裏內存會一直佔用
  1. 數組用 delete 而非 delete[]:例如:
   int* arr = new int[10];
   delete arr;  // 錯誤!應該用 delete[] arr;

這樣只會釋放數組第一個元素的內存,剩下的 9 個元素內存永遠不會被釋放。

  1. 重複釋放內存:同一個指針不能 delete 兩次,否則會導致程序崩潰:
   int* p = new int;
   delete p;
   delete p;  // 錯誤!重複釋放,未定義行爲

總結

動態內存分配讓我們可以在運行時靈活管理內存,核心工具是 newdelete
- new 用於在堆上分配單個對象或數組內存,語法分別爲 new 類型new 類型[大小]
- delete 用於釋放單個對象的內存,delete[] 用於釋放數組的內存;
- 務必用對應方式釋放內存(單個對象用 delete,數組用 delete[]),避免內存泄漏或程序崩潰。

合理使用動態內存,可以讓程序更高效地利用內存資源,但要時刻注意內存的分配與釋放,養成良好的編程習慣。

小夜