《C++ Primer》阅读笔记(十二)动态内存

本文是《C++ Primer》第12章的读书笔记,主要讨论动态内存管理和智能指针,包括shared_ptr、unique_ptr、weak_ptr的使用,动态数组的管理,以及如何直接管理内存。强调了智能指针在异常处理中的优势,以及避免空悬指针的重要性。
摘要由CSDN通过智能技术生成

第12章 动态内存

程序用堆(heap)来存储动态分配(dynamically allocate)的对象。动态对象的生存期由程序控制。

动态内存与智能指针(Dynamic Memory and Smart Pointers)

C++中的动态内存管理通过一对运算符完成:new在动态内存中为对象分配空间并返回指向该对象的指针,可以选择对对象进行初始化;delete接受一个动态对象的指针,销毁该对象并释放与之关联的内存。

新标准库提供了两种智能指针(smart pointer)类型来管理动态对象。智能指针的行为类似常规指针,但它自动释放所指向的对象。这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个指针指向同一个对象;unique_ptr独占所指向的对象。标准库还定义了一个名为weak_ptr的伴随类,它是一种弱引用,指向shared_ptr所管理的对象。这三种类型都定义在头文件memory中。

shared_ptr类(The shared_ptr Class)

智能指针是模板,创建时需要指明指针可以指向的类型。默认初始化的智能指针中保存着一个空指针。

shared_ptr<string> p1;      // shared_ptr that can point at a string
shared_ptr<list<int>> p2;   // shared_ptr that can point at a list of ints

shared_ptrunique_ptr都支持的操作:

shared_ptr独有的操作:

make_shared函数(定义在头文件memory中)在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr

// shared_ptr that points to an int with value 42
shared_ptr<int> p3 = make_shared<int>(42);
// p4 points to a string with value 9999999999
shared_ptr<string> p4 = make_shared<string>(10, '9');
// p5 points to an int that is value initialized
shared_ptr<int> p5 = make_shared<int>();

进行拷贝或赋值操作时,每个shared_ptr会记录有多少个其他shared_ptr与其指向相同的对象。

auto p = make_shared<int>(42);  // object to which p points has one user
auto q(p);  // p and q point to the same object
            // object to which p and q point has two users

 每个shared_ptr都有一个与之关联的计数器,通常称为引用计数(reference count)。拷贝shared_ptr时引用计数会递增。例如使用一个shared_ptr初始化另一个shared_ptr,或将它作为参数传递给函数以及作为函数的返回值返回。给shared_ptr赋予新值或shared_ptr被销毁时引用计数会递减。例如一个局部shared_ptr离开其作用域。一旦一个shared_ptr的引用计数变为0,它就会自动释放其所管理的对象。

auto r = make_shared<int>(42);  // int to which r points has one user
r = q;  // assign to r, making it point to a different address
        // increase the use count for the object to which q points
        // reduce the use count of the object to which r had pointed
        // the object r had pointed to has no users; that object is automatically freed

shared_ptr的析构函数会递减它所指向对象的引用计数。如果引用计数变为0,shared_ptr的析构函数会销毁对象并释放空间。

如果将shared_ptr存放于容器中,而后不再需要全部元素,而只使用其中一部分,应该用erase删除不再需要的元素。

程序使用动态内存通常出于以下三种原因之一:

  • 不确定需要使用多少对象。(容器类)
  • 不确定所需对象的准确类型。 (十五章)
  • 需要在多个对象间共享数据。(本节例子)

直接管理内存(Managing Memory Directly)

相对于智能指针,使用newdelete管理内存很容易出错。

默认情况下,动态分配的对象是默认初始化的。所以内置类型或组合类型的对象的值将是未定义的,而类类型对象将用默认构造函数进行初始化。

string *ps = new string;    // initialized to empty string
int *pi = new int;     // pi points to an uninitialized int

可以使用值初始化方式、直接初始化方式、传统构造方式(圆括号())或新标准下的列表初始化方式(花括号{})初始化动态分配的对象。

int *pi = new int(1024);            // object to which pi points has value 1024
string *ps = new string(10, '9');
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值