【内存与智能指针】

内存类型

栈内存

定义在函数内的非static对象

堆内存

在程序运行时分配的对象

静态内存

局部static对象、类static数据成员、定义在任何函数之外的变量

内存问题

内存泄漏

忘记释放内存

非法内存指针

尚有指针引用的内存被释放

智能指针

shared_prt:允许多个指针指向同一对象

unique_prt:“独占”指向对象

weak_prt:指向shared_ptr所管理的对象

都在memory头文件中

shared_ptr类

make_shared函数

在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr。

例:shared_ptr p = make_shared(10,‘9’)

weak_ptr

  1. 是一种不控制所指向对象生命期的指针,指向由也给shared_ptr管理的对象
  2. 最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指针

unique_ptr

  1. 一个unique_ptr“拥有”它所指向的对象
  2. 没有类似make_shared的函数返回unique_ptr
  3. 没有赋值、拷贝操作

拷贝:unique_ptr p1(p2);

赋值:p1 = p3;

​ 3.1可以拷贝或赋值一个将要被销毁的unique_ptr。例如作为参数或返回

​ 3.2 “可以”(编译不出错,但可能出现悬空指针)拷贝一个普通指针或取地址。如下

int *p = new int(2048);
int x;
unique_ptr<int> p1(p);    //出现悬空指针
unique_ptr<int> p2(&x);    //原始对象非new得来,故unique_ptr执行delete出错
  1. 通过release或reset移交控制权
unique_ptr<int> p2(p1.release());



unique_ptr<int> p3(new string("abc"));

p2.reset(p3.release());

注:release会切断unique_ptr和它原来管理的对象简的关系。release返回的指针通常用来初始化另一个智能指针或赋值另一个智能指针。

智能指针的计数实现

这个计数器实际上是存储在 shared_ptr 的内部,而不是存储在所指向的对象上。

如果有多个智能指针指向同一个对象,每个智能指针的计数器都会递增。当一个新的智能指针指向了已经被其他智能指针管理的对象时,被管理对象的引用计数会增加。

递增:

①通过一个shared_ptr初始化另一个shared_ptr

②作为参数传递给一个函数

③作为函数返回值

递减:

①给shared_ptr赋新值

②shared_ptr离开作用域

销毁:计数器变为0

动态数组

  1. 分配一个动态数组,需要在类型名后跟一对方括号。如下:

    int *p = new int[get_size()]
    
  2. 分配一个数组会得到一个元素类型的指针

  3. 初始化动态数组。如下

    int * p1 = new int[10](); //值初始化
    
  4. 动态分配一个大小为0的数组是合法的

    char *cp = new char[0];
    
  5. delete动态分配对象时一定要分清是不是数组

    delete p;   //p必须指向一个动态分配的对象或空
    delete [] p;    //p必须指向一个动态分配的数组或空
    
  6. 标准库提供管理new分配数组的unique_ptr版本,但shared_ptr没有

    unique_ptr<int[]> up(new int[10])
    

allocator类

string * const p = new string[n]
  1. 将内存分配与对象构造组合在一起可能会导致不必要的浪费。因为动态内存是默认初始化的。例如本例可能不需要n个string
allocator<string> alloc;
auto const p = alloc.allocate(n);
  1. 定义一个allocator对象必须指明这个allocator可以分配的对象类型。最终结果是分配n个未初始化的string对象。
auto q = p;
alloc.construct(q++,10,'c');
while(p != q)
	alloc.destroy(--q);
  1. allocator分配的内存是未构造的,需要对内存construct后再访问内容。当对象使用完毕后,需要调用destroy来销毁它们。
alloc.deallocate(p,n);
  1. 销毁后的内存可以归还给系统

程序使用动态内存的原因

1、程序不知道自己需要使用多少对象

2、程序不知道所需对象的准确类型

3、程序需要在多个对象间共享数据

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值