【C++】C++11 动态内存管理
内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能。
伟大的Bill Gates 曾经失言:
640K ought to be enough for everybody — Bill Gates 1981
程序员们经常编写内存管理程序,往往提心吊胆。如果不想触雷,唯一的解决办法就是发现所有潜伏的地雷并且排除它们,躲是躲不了的。
我们在程序运行的过程中,经常出现段错误、内存持续增大等,是C++显式内存管理存在的问题,主要归纳为以下几点:
1. 野指针:一些内存单元已经释放,但之前指向它的指针还在使用。
2. 重复释放:程序试图释放已经被释放过的内存单元。
3. 内存泄漏:没有释放不再使用的内存单元。
4. 缓冲区溢出:数组越界。
5. 不配对的new[]/delete
针对以上1~3的问题,C++标准中提供了智能指针来解决。
智能指针是基于RAII(Resource Acquisition Is Initialization)机制实现的类(模板),具有指针的行为(重载了operator*与operator->操作符)。当对象创建的时候,进行初始化;离开其作用域后,通过自动调用析构函数释放资源。
C++98中,智能指针通过一个模板类型"auto_ptr"来实现,auto_ptr对象通过初始化指向由new创建的动态内存,当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有的动态内存自动释放。即使发生异常,通过异常的栈展开过程也能将动态内存释放。但其有一些缺点:
- 赋值和拷贝操作的目标对象会先释放其原来所拥有的对象
- auto_ptr 析构的时候调用的是delete,所以不能用auto_ptr管理数组指针
因此,在C++11标准中,改用unique_ptr、shared_ptr及weak_ptr等智能指针来对动态内存进行管理。auto_ptr为了兼容以前的代码被遗留下来,不建议使用。