
P.8: 勿泄漏任務資源
原因
隨著時間的推移,即使是資源的緩慢增長也會耗盡這些資源的可用性,這對于長時間運行的程序特別重要,但也是負責任的編程行為的基本部分。
糟糕的例子
void f(char* name){ FILE* input = fopen(name, "r"); // ... if (something) return; // 糟糕:如果 something == true,文件句柄就泄漏了 // ... fclose(input);}
優先使用RAII:
void f(char* name){ ifstream input {name}; // ... if (something) return; // OK: 沒有泄漏 // ...}
參考: 資源管理部分
注意
泄漏通俗地說就是“任何沒有被清理的東西”,更重要的分類是“任何不能再被清理的東西”。例如,在堆上分配了一個對象,然而丟失了指向該塊內存(分配)的指針。 不應將此規則應用在程序關閉期間需返回長生命周期對象的分配(譯注:在程序退出期間的內存分配可以不需要遵守這些規則),例如,依賴于系統保證的清理可以簡化代碼,比如關閉文件和在進程關閉時釋放內存。然而,依賴于隱式清理的抽象也同樣簡單,而且通常更安全。
注意
使用生命周期安全性剖面(profile) 來消除泄漏,當與RAII提供的資源安全相結合時,就沒了"垃圾回收"的需求。當使用類型和邊界剖面(profiles)時,你可以獲得由工具保證的類型和資源安全。
實施
- 查看指針:將它們分為非所有者(默認)和所有者(owner),在可行的地方,用標準庫資源句柄替換所有者(如上面的示例所示),或者使用GSL中的owner來標記所有者。
- 查看裸用的new和delete
- 查看已知返回原始指針的資源分配函數(如fopen, malloc 和 strdup)