CppCoreGuidelines P.8 不要泄漏任何资源
29 December 2021
如果系统长期运行的,哪怕没有及时释放很小的资源,都有可能导致系统资源耗尽。因此,及时释放系统资源是一种负责任的编程态度。
void f(char* name) { FILE* input = fopen(name, "r"); // ... if (something) return; // bad: if something == true, a file handle is leaked // ... fclose(input); }
以上例程中,如果 something
为真,函数直接返回了,没有及时关闭 input
文件结构体,产生资源泄漏。
void f(char* name) { ifstream input {name}; // ... if (something) return; // OK: no leak // ... }
改用 ifstream
文件输入对象可以避免资源泄漏。当函数返回的时候,自动调用解构函数释放内存数据。
所谓的泄漏(leak)通俗的讲,就是出现任何没有及时释放的资源(anything that isn’t cleaned up)。细分下去,更重要的一类泄漏是:任何不能被释放的资源(anything that can no longer be cleaned up)。比如在堆中分配一个对象,然后运行过程中,对象的地址指针被覆盖掉了。于是,就再也没办法释放这个对象了。所以,对任何中途结束的程序,要么释放内存,要么把分配的对象返回给上层函数继续使用或者晚些时候释放。
建议:
- 审查指针的使用。区分有主和无主指针。如以上例子用标准库资源句柄替换。或者用 GSL 中的
unique_ptr
和shared_ptr
标记指针所有权。 审查暴露的
new
和delete
,相对的是定义了释放规则的封装的new
:shared_ptr<int> p(new int[10], [](int* p) {delete []p;})
- 审查返回裸指针(raw pointer)的资源分配函数。比如:
fopen
,malloc
,strdup
.