標準模式
class MyClass {
int* pData;
public:
MyClass() : pData(new int[100]) {}
~MyClass() {
delete[] pData; // 1. 釋放堆記憶體,防洩漏
pData = nullptr; // 2. 置空,防野指針 (dangling pointer)
}
};
為何要先 delete 再置 nullptr?
| 步驟 | 作用 | 若省略後果 |
delete[] pData | 歸還記憶體給堆管理器,調用元素解構函數 | 記憶體洩漏,程式長期運行耗盡記憶體 |
pData = nullptr | 切斷指針與已釋放記憶體的關聯 | 後續誤用 if (pData) 判斷為真,導致**使用已釋放記憶體 (UAF)**、雙重釋放、崩潰 |
現代 C++ 最佳實踐:智慧指針取代手動管理
#include
class MyClass {
std::unique_ptr pData; // 單一擁有權,自動 delete[]
public:
MyClass() : pData(std::make_unique(100)) {}
// 無需寫解構函數,離開作用域自動釋放,且無野指針風險
};
unique_ptr:獨佔所有權,不可複製,可移動,零開銷。
shared_ptr:共享所有權,引用計數,適合多擁有者場景。
vector:若為動態陣列,直接用 std::vector 更簡潔安全。
遺留代碼改造建議
- 全域搜尋
new[]/delete[]、new/delete。
- 評估擁有權語意,替換為
unique_ptr/vector/string。
- 若必須保留裸指針 (如 C API 介面),嚴格遵循「建構獲取資源、解構釋放資源 (RAII)」並置
nullptr。
- 上一篇文章: Gson 解析 JSON 所有欄位為 null/0:欄位命名、修飾符與註解完整排查清單
- 下一篇文章: MySQL 命令列登入失敗:參數 -w 與 -u 混淆
Copyright ©
程式碼之家 All Rights Reserved