在 C++ 程式設計中,動態記憶體管理是核心技能之一。透過 new 運算子在執行期配置記憶體,並以 delete 釋放不再使用的空間,能讓程式更靈活地處理資料結構。本文將系統性介紹動態記憶體分配的語法、陣列配置、失敗處理及最佳實務。
new 運算子後接資料型別,成功時回傳指向配置記憶體起始位址的指標;失敗則拋出 std::bad_alloc 例外(舊標準可能回傳 nullptr)。
// 單一物件
int* ptr = new int; // 配置一個 int
int* ptr = new int(10); // 配置並初始化為 10
// 陣列配置
int* arr = new int[5]; // 配置 5 個 int 陣列
int* arr = new int[5]{1,2,3,4,5}; // C++11 列表初始化
配置的記憶體必須手動釋放,否則會造成記憶體洩漏。單一物件用 delete,陣列必須用 delete[]。
delete ptr; // 釋放單一物件
delete[] arr; // 釋放陣列(務必加上 [])
現代 C++ 標準規定 new 失敗會拋出 std::bad_alloc,建議使用 try-catch 捕捉,或使用 new (std::nothrow) 取得空指標而非例外。
// 方式一:例外處理
try {
int* p = new int[1000000000];
} catch (const std::bad_alloc& e) {
std::cerr << "配置失敗:" << e.what() << '\n';
}
// 方式二:nothrow 版本
int* p = new (std::nothrow) int[1000000000];
if (!p) { /* 處理失敗 */ }
delete 會導致未定義行為。delete arr 只會解構第一個元素,其餘記憶體未釋放。建議:優先使用智慧指標(std::unique_ptr、std::shared_ptr)與標準容器(std::vector、std::string),讓 RAII 機制自動管理生命週期,減少手動 new/delete 的風險。
#include <iostream>
#include <new> // std::nothrow, std::bad_alloc
int main() {
// 1. 基本配置與釋放
int* single = new int(42);
std::cout << "值:" << *single << '\n';
delete single;
// 2. 陣列配置
const size_t n = 5;
int* arr = new int[n]{1, 2, 3, 4, 5};
for (size_t i = 0; i < n; ++i) std::cout << arr[i] << ' ';
std::cout << '\n';
delete[] arr;
// 3. 錯誤處理示範
int* big = new (std::nothrow) int[1000000000];
if (!big) std::cerr << "大型陣列配置失敗\n";
delete[] big; // 刪除空指標安全
return 0;
}
掌握 new/delete 是 C++ 程式設計師的基本功,但現代開發應盡量以智慧指標與容器取代手動管理,寫出更安全、可維護的程式碼。