【Primer C++学习笔记】12. 动态内存

12. 动态内存

静态内存用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量;栈内存用来保存定义在函数内的非static对象。分配在静态内存或栈内存中的对象由编译器自动创建和销毁。除了静态内存和栈内存,程序还有一个内存池称为自由空间或堆,程序用堆存储动态分配的对象。动态分配对象的生存期与在哪里创建无关,只有当显式地被释放时才会被销毁。

12.1 动态内存与智能指针

12.1.1 shared_ptr类

12.1.2 直接管理内存

12.1.5 unique_ptr

12.2 动态数组

12.2.1 new和数组

12.2.2 allocator类 

 12.3 使用标准库:文本查询程序


12.1 动态内存与智能指针

动态内存的管理通过new和delete完成:

  • new:在动态内存中为对象分配空间并返回一个指向该对象的指针;
  • delete:接受一个动态对象的指针销毁该对象并释放与之关联的内存。

为了更容易使用动态内存,标准库提供两种智能指针类型(shared_ptr允许多个指针指向同一个对象,unique_ptr独占指向的对象)管理动态对象,它负责自动释放指向的对象,定义在memory头文件中。

 

12.1.1 shared_ptr类

解引用一个智能指针返回它指向的对象,在一个条件判断中使用智能指针效果为检测它是否为空:

 

make_shared<T>(args):

最安全的分配和使用动态内存的方法,调用make_shared函数可以在动态内存中分配一个对象并初始化,返回指向此对象的shared_ptr。

 

shared_ptr<T>p(q):

进行拷贝或赋值操作时,每个shared_ptr都会记录有多少其它shared_ptr指向相同的对象(基于引用计数)。

当shared_ptr计数器变为0时会自动释放自己所管理的对象(通过析构函数):

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

  • 程序不知道自己需要使用多少对象;
  • 程序不知道所需对象的准确类型;
  • 程序需要在多个对象间共享数据;

这里举例说明第三种原因:

目前为止使用过的类中分配的资源与对应对象生存期一致,例如每个vector拥有自己的元素,拷贝一个vector时,原vector和副本vector中的元素相互分离:

 

定义Blob类保存一组元素,希望Blob对象的不同拷贝之间共享相同的元素(拷贝一个Blob时,原Blob对象及其拷贝应该引用相同的底层元素):

当一个vector被销毁时,其中的元素也被销毁,而Blob对象共享相同的元素,b2被销毁时其中的元素必须保留。 

 定义一个管理string的StrBlob类:

 size、empty、push_back成员通过指向底层的vector的data成员完成工作。

构造函数:

 

元素访问成员函数:

pop_back、front、back访问vector中的元素,在访问元素前用check检查元素是否存在。

check接受一个string参数将其传递给异常处理程序:

其他成员调用check后再完成工作:

12.1.2 直接管理内存

用new和delete分配和释放动态内存的方法相对于智能指针非常容易出错。

new:动态分配和初始化对象

new在自由空间构造一个int型对象并返回指向该对象的指针。 

delete:传递的指针必须指向动态分配的内存

12.1.5 unique_ptr

只能有一个unique_ptr指向一个指定对象,当unique_ptr被销毁时,它指向的对象也被销毁。unique_ptr不支持普通的拷贝或赋值操作。

 


12.2 动态数组

12.2.1 new和数组

返回一个元素类型的指针。 

12.2.2 allocator类 

new和delete将构造/析构与内存分配/释放组合在了一起,使用allocator类可以将内存分配和对象构造分离开,当一个allocator对象分配内存时,会根据给定的对象类型确定恰当的内存大小。


 12.3 使用标准库:文本查询程序

程序允许用户在一个给定文件中查询单词,查询结果是单词在文件中出现的次数及其所在行的列表。例如在文本中寻找单词element,输出结果为:

需求分析:

实现思路:

定义一个保存输入文件的类TextQuery,包含一个vector保存输入文件的文本和一个map关联每个单词和它出现的行号set,以及读取给定输入文件的构造函数和一个执行查询的操作;

定义一个返回所有查询结果的类QueryResult,有一个print函数进行结果打印。

TextQuery:

构造函数:

定义一个query函数:

 

QueryResult:

  • string:保存查询单词
  • shared_ptr:指向保存输入文件的vector 
  • shared_ptr:指向保存单词出现行号的set

最后打印结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值