设为首页 加入收藏

TOP

1.7 插曲:系统地避免各种指针错误
2013-10-07 16:00:47 来源: 作者: 【 】 浏览:66
Tags:1.7 插曲 系统 避免 各种 指针 错误

1.7 插曲:系统地避免各种指针错误

我同意孟岩说的9 “大部分用C 写的上规模的软件都存在一些内存方面的错误,需要花费大量的精力和时间把产品稳定下来。”举例来说,就像Nginx 这样成熟且广泛使用的C 语言产品都会不时暴露出低级的内存错误。

内存方面的问题在C++(www.cppentry.com) 里很容易解决,我第一次也是最后一次见到别人的代码里有内存泄漏是在2004 年实习那会儿,我自己写的C++(www.cppentry.com) 程序从来没有出现过内存方面的问题。

C++(www.cppentry.com) 里可能出现的内存问题大致有这么几个方面:

1. 缓冲区溢出(buffer overrun)。

2. 空悬指针/野指针。

3. 重复释放(double delete)。

4. 内存泄漏(memory leak)。

5. 不配对的new[]/delete。

6. 内存碎片(memory fragmentation)。

正确使用智能指针能很轻易地解决前面5 个问题,解决第6 个问题需要别的思路,我会在§9.2.1 和§A.1.8 探讨。

1. 缓冲区溢出:用std::vector<char>/std::string 或自己编写Buffer class 来

管理缓冲区,自动记住用缓冲区的长度,并通过成员函数而不是裸指针来修改缓冲区。

2. 空悬指针/野指针:用shared_ptr/weak_ptr,这正是本章的主题。

3. 重复释放:用scoped_ptr,只在对象析构的时候释放一次。

4. 内存泄漏:用scoped_ptr,对象析构的时候自动释放内存。

5. 不配对的new[]/delete:把new[] 统统替换为std::vector/scoped_array。

正确使用上面提到的这几种智能指针并不难,其难度大概比学习使用std::

vector/std::list 这些标准库组件还要小,与std::string 差不多,只要花一周的时间去适应它,就能信手拈来。我认为,在现代的C++(www.cppentry.com) 程序中一般不会出现delete语句,资源(包括复杂对象本身)都是通过对象(智能指针或容器)来管理的,不需要程序员还为此操心。

在这几种错误里边,内存泄漏相对危害性较小,因为它只是借了东西不归还,程序功能在一段时间内还算正常。其他如缓冲区溢出或重复释放等致命错误可能会造成安全性(security 和data safety)方面的严重后果。

需要注意一点:scoped_ptr/shared_ptr/weak_ptr 都是值语意,要么是栈上对象,或是其他对象的直接数据成员,或是标准库容器里的元素。几乎不会有下面这种用法:

  1. shared_ptr<Foo>pFoo = new shared_ptr<Foo>(new Foo); // WRONG semantic 

还要注意,如果这几种智能指针是对象x 的数据成员,而它的模板参数T 是个incomplete 类型,那么x 的析构函数不能是默认的或内联的,必须在.cpp 文件里边显式定义,否则会有编译错或运行错(原因见§10.3.2)。
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.6 神器shared_ptr/weak_ptr 下一篇1.8 应用到Observer 上

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·MySQL 安装及连接-腾 (2025-12-25 06:20:28)
·MySQL的下载、安装、 (2025-12-25 06:20:26)
·MySQL 中文网:探索 (2025-12-25 06:20:23)
·Shell脚本:Linux Sh (2025-12-25 05:50:11)
·VMware虚拟机安装Lin (2025-12-25 05:50:08)