动态内存与智能指针

动态内存与智能指针

1 对象和内存

程序中对象的种类和生命周期

  • 全局对象:在程序启动时分配,在程序结束时销毁。
  • 局部自动对象:在进入定义它的程序块时被创建,在离开块时销毁。
  • 局部static对象:在第一次使用前分配,在程序结束时销毁。
  • 动态分配对象:动态分配的对象的生存期由程序来控制,只有当它们被程序显式地释放时,这些对象才会被销毁。

内存的种类

  • 静态内存:用来存放局部static对象、类static数据成员以及定义在任何函数之外的变量。

  • 栈内存:用来存放定义在函数内的非static对象。

  • 内存池(自由空间、):用来存储动态分配的对象,即那些在程序运行时分配的对象。

【注】分配在静态或栈内存中的对象由编译器自动创建和销毁,而堆中的动态对象则需要我们在代码中显式销毁。

2 动态内存的管理

在C++中,动态内存的管理是通过一对运算符来完成的:

  • new:在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象进行初始化。
  • delete:接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。

3 智能指针

由于动态内存的使用很容易出现问题,因为确保在正确的时间释放内存是非常困难的。有时候我们会忘记释放内存,在这种情况下就会产生内存泄漏;有时候在尚有指针应用内存的情况下我们就释放了它,这种情况下就会产生引用非法内存的指针。

为了更容易、更安全的使用动态内存,C++11提供了两种智能指针(smart point)类型来管理动态对象,都在头文件之中。智能指针的行为类似于常规指针,重要的区别是它负责自动释放所指向的对象。

  • shared_ptr:允许多个指针指向同一个对象。
  • unique_ptr:该指针“独占”所指向的对象。

shared_ptr和unique_ptr都支持的操作

代码操作
shared_ptr<T> sp创建一个空智能指针(共享),可以指向类型为T的对象
unique_ptr<T> up创建一个空智能指针(独占),可以指向类型为T的对象
p将p用作一个条件判断,若p指向一个对象,则为true
*p解引用,或者p指向的对象
p->mem等价于(*p).mem
p.get()返回p中保存的指针。要小心使用,若智能释放了其对象,返回的指针所指向的对象也就消失了
swap(p,q)交换p和q中的指针
p.swap(q)同上

shared_ptr独有的操作

代码操作
make_shared<T>(args)返回一个shared_ptr,指向一个动态分配的类型为T的对象。使用args初始化此对象。
shared_ptr<T> p(q)p是shared_ptr q的拷贝;此操作会递增q中的引用计数。q中的指针必须能够转换为T*
p = qp和q都是shared_ptr,所保存的指针必须能够互相转换。此操作会递减p的引用计数,递增q的引用计数;若p的引用计数为0,则将其管理的原内存释放
p.unique()若p.use_count()为1,返回true,否则返回false
p.use_count()返回与p共享对象的智能指针数量;可能很慢,主要用于调试

智能指针的创建和初始化

类似于vector,智能指针也是模版。因此,当我们创建一个智能指针时,必须在尖括号内给出类型。

shared_ptr<string> p1;		//创建一个指向string的智能指针
shared_ptr<list<int>> p2;	//创建一个指向list<int>的智能指针

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

shared_ptr<int> p3 = make_shared<int>(42);				//指向一个值为42的int的shared_ptr
shared_ptr<string> p4 = make_shared<string>(10, '9'); 	//指向一个值为“9999999999”的string的shared_ptr
shared_ptr<string> p5 = make_shared<int>();				//p5指向一个值初始化的int,即值为0
auto p6 = make_shared<vector<string>>();				//也可以用auto来定义一个shared_ptr对象
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页