C/C++软件工程实现中,内存泄露可能是一个让众多程序员懊恼的问题. 内存泄露问题是如此普遍并且被认为是难以解决,标明内存泄露不是一个理论上的问题, 而是一个实践中的问题. 假若它是一个理论上的问题, 那么它肯定早就从理论上加以解决而不再是一个问题.
软件工程实践中, 应该努力采用良好的设计策略和代码习惯来尽量避免内存泄露; 说避免并非是逃避困难而是规避内存泄漏遍及代码导致不可控的风险和测试阶段导致的疲于奔命.
下面总结几个关乎内存泄漏的设计原则:
1. 尽量不设计内部分配内存而该内存传到外部使用的接口;
2. 当内存是系统或模块内部分配并且需要传给外部时(不可更改性接口需求时), 为了在特定上下文/线程/环境终止时清理内部分配的与之相关的内存, 那么这时系统需要引入一个也许并不复杂的全局内存管理器;
3. 与特定上下文/线程/环境系统所有内存分配/释放操作都经由这个内存管理器来追踪; 在软件规模增大时, 多种分配方式的使用只会带来混乱从而不可避免的导致内存泄露;
4. 对于与特定上下文/线程/环境相关的接口, 外部无法预先知道缓冲区大小需求的情况(如IO, 一般有内部缓冲区且有足够的状态和信息), 或者与特定上下文无关,但能根据传入参数知道需要缓冲大小的接口(如协议包序列化参数含大小), 接口需要支持:
首先传递NULL缓冲区指针,返回需要的缓冲区大小;
传入的缓冲区大小太小时,返回缓冲小错误码;
传入的缓冲区足够时,拷贝输出数据.
5. 系统中与特定上下文无关的接口或者业已存在的, 外部无法预先知道缓冲区大小需求的情况, 使用特定上下文进行封装, 其分配的内存注册到内存管理器中, 使用完毕后需要调用内存管理器释放接口显式释放, 尽量将其使用控制在特定层次内.
6. 使用内存泄露工具检查整个系统.