初學者疑惑:既然可以重複給同一個陣列賦值,為何還需要 new/delete 動態分配記憶體?固定幾個陣列重複使用不就省記憶體了嗎?
| 維度 | 固定陣列重複使用 | new/delete 動態分配 |
|---|---|---|
| 記憶體彈性 | 編譯期固定大小,無法適應執行期變化的資料量 | 執行期依需求分配任意大小,用完釋放 |
| 大型資料處理 | 頻繁讀寫同一塊記憶體造成快取污染、資料覆蓋風險 | 各物件獨立記憶體區塊,隔離性好 |
| 物件生命週期 | 隨作用域固定,難以跨函式/模組共享 | 程式設計師完全掌控建構/解構時機 |
| 多型與繼承 | 無法存放衍生類物件(切割問題) | 基類指標指向衍生類物件,支援多型 |
| 資料結構實作 | 難以實作鏈表、樹、圖等動態結構 | 天然支援節點動態增減 |
new/delete 確有分配開銷,但可透過物件池、智慧指標(unique_ptr, shared_ptr)、標準容器(vector, list)緩解。// 推薦:使用標準容器與智慧指標,避免手動 new/delete
std::vector dynamicArray; // 自動擴容
dynamicArray.reserve(1000); // 預留空間減少重新分配
std::unique_ptr obj = std::make_unique(); // 單一擁有權
std::shared_ptr res = std::make_shared(); // 共享擁有權
// 若確需手動管理(如效能熱點、C API 介接),封裝 RAII 類別
class Buffer {
int* data;
size_t size;
public:
Buffer(size_t n) : data(new int[n]), size(n) {}
~Buffer() { delete[] data; }
// 禁止複製,支援移動語意
Buffer(const Buffer&) = delete;
Buffer& operator=(const Buffer&) = delete;
Buffer(Buffer&& other) noexcept : data(other.data), size(other.size) {
other.data = nullptr; other.size = 0;
}
};
固定陣列適合極小、固定大小、生命週期簡單的場景。只要涉及不確定資料量、跨模組傳遞、多型、複雜資料結構,動態記憶體管理(或更高層級的容器/智慧指標)是不可或缺的工具,能顯著提升程式的正確性、可維護性與擴充性。