He Zean · 12011323 CS205 ◦ Project 4: Class Matrix 5 / 27
较为安全的内存管理 在构造函数中使用 try-catch 以处理可能的部分构造产生的内存泄露,析构函数“吸
收”所有异常避免引发 terminate 导致的程序终止时大规模内存无法释放(更多分析见 4.1 节)。
有效性检查 在前面的 project 中只注重了矩阵乘法的性能提升,假设输入均有效。而本“工程”需要处理
各种可能的输入,因此需要设置检查以保证鲁棒性6。相较于出错时打印提示并退出程序,这里选择抛出异
常(见 2.4 节),并由主调函数决定如何处理,更加灵活。
强 制 类 型 转 换 提 供 了 SmartPtr(const SmartPtr &rhs) 作 为 拷 贝 构 造 器 和 explicit SmartPtr(const
SmartPtr<V> &op) 供强制类型转换(如 project 3 中讨论,在数据类型不便使用 SIMD 指令集时,循
环展开能有效加速),但要注意的是对于非 primitive type <T>,用户在将其交给 SmartPtr 代为保管时需要
提供对应的转换构造函数。
正确性 经多种测试,本代理类能很好的应对错误的参数、申请内存时的异常等情况,且在出作用域后能
在正确的时机删除原始数据区,不漏删(见测试样例中的 leak report)不重删(故意在删除后不将指针设
为 nullptr,再次删除必然导致系统杀死程序)。另外,注意到 memory 头文件中定义的 smart_ptr 存在典
型的引用计数法的缺陷——无法释放环形引用,这是出于适用性考虑,其计数器在于指针,而非资源;而
本代理类对计数器的管理较为“扁平化”,是 Matrix 访问“资源池”的代理,经过测试和理论分析,能有
效避免内存不释放的问题。
典型的环形引用导致内存释放 (图源:简书)
6实际上,受时间所限,编写代码时所能想到的异常必然远不足以覆盖所有可能;另外,在真实的工程代码中,处理各种可能异常
的代码量甚至超过业务代码量。
评论0