第3章 内存管理
内存管理一直是令C++(www.cppentry.com)程序员最头疼的工作,C++(www.cppentry.com)继承了C那高效而又灵活的指针,使用起来稍微不小心就会导致内存泄漏(memory leak)、"野"指针(wild pointer)、访问越界(access denied)等问题。曾几何时,C++(www.cppentry.com)程序员曾经无限地向往Java、C#等语言的垃圾回收机制。虽然C++(www.cppentry.com)标准提供了智能指针std::auto_ptr,但并没有解决所有问题。
阅读完本章,你会了解到高效的内存管理方法,彻底忘记"栈"(Stack)、"堆"(Heap)等内存分配相关的术语,并且还会发现,Boost为C++(www.cppentry.com)提供的解决方案可能要比Java和C#等其他语言更好。
3.1 smart_ptr库概述
计算机系统中资源有很多种,内存是我们最常用到的,此外还有文件描述符、socket、操作系统handle、数据库连接等等,程序中申请这些资源后必须及时归还系统,否则就会产生难以预料的后果。
3.1.1 RAII机制
为了管理内存等资源,C++(www.cppentry.com)程序员通常采用RAII机制(资源获取即初始化,Resource Acquisition Is Initialization),在使用资源的类的构造函数中申请资源,然后使用,最后在析构函数中释放资源。
如果对象是用声明的方式在栈上创建的(一个局部对象),那么RAII机制会工作正常,当离开作用域时对象会自动销毁从而调用析构函数释放资源。但如果对象是用new操作符在堆上创建的,那么它的析构函数不会自动调用,程序员必须明确地用对应的delete操作符销毁它才能释放资源。这就存在着资源泄漏的隐患,因为这时没有任何对象对已经获取的资源负责,如果因某些意外导致程序未能执行delete语句,那么内存等资源就永久地丢失了。例如:
- int *p = new class_need_resource; //对象创建,获取资源
- .. //可能发生异常导致资源泄漏
- delete p; //析构释放资源
new、delete以及指针的不恰当运用是C++(www.cppentry.com)中造成资源获取/释放问题的根源,能否正确而明智地运用delete是区分C++(www.cppentry.com)新手与熟手的关键所在 。但很多人--即使是熟练的C++(www.cppentry.com)程序员,也经常会忘记调用delete。