【C++ Primer读书笔记】第12章 动态内存


动态分配的对象存储在堆上,生存期与作用域无关,只有当显式地被释放时,这些对象才会销毁。

动态内存与智能指针

智能指针:负责在合适的时机自动释放所指向的对象

  • shared_ptr:允许多个shared_ptr指向同一个对象
  • unique_ptr:独占所指向的对象
  • weak_ptr:弱引用,不占引用计数,指向shared\_ptr所指向的对象

shared_ptr

make_shared

在动态内存中构造一个对象,并返回指向它的shared_ptr

shared_ptr<int> p1 = make_shared<int>(42);
auto p2 = make_shared<string>(10, '9');
auto p3 = make_shared<int>();   // 值初始化
auto p4(p3);    // p4和p3指向同一个对象
引用计数

引用计数增加:拷贝shared_ptr时,例如用一个shared_ptr初始化另一个shared_ptr,作为函数实参,作为函数的返回值…

引用计数减少:让shared_ptr指向其它的对象,shared_ptr被销毁(离开作用域等)…

当引用计数为0时,shared_ptr就会自动释放自己所管理的对象

管理shared_ptr的容器,如果不再需要某些元素,应该用erase删除,使shared_ptr被销毁

直接管理内存

new
string *ps = new string;    // 默认初始化为空string
Sales_data *p = new Sales_data;     // 使用默认构造函数初始化

/* 内置类型 默认初始化和值初始化有区别 */
int *pi1 = new int;      // 默认初始化 pi1的值未定义
int *pi2 = new int();   // 值初始化为0
delete

传递给delete的指针必须指向动态分配的内存,或者空指针。释放一块并非由new分配的内存,或者将同一块内存释放多次,行为是未定义的。delete后,指针仍然保存着已释放的动态内存的地址。

shared_ptr和new结合使用

shared_ptr<int> p1 = new int(1024); // 错误,接受指针参数的智能指针构造函数是explicit的
shared_ptr<int> p2(new int(1024));

默认情况下,一个用来初始化智能指针的普通指针必须指向动态内存,因为智能指针默认使用delete释放它所关联的对象。也可以自定义释放操作。

unique_ptr

某个时刻只能有一个unique_ptr指向某个对象,当unique_ptr被销毁时,它所指向的对象也会被销毁。unique_ptr不支持拷贝或赋值。

unique_ptr<string> p1(new string("abc"));
unique_ptr<string> p2(p1.release());    // release将p1置为空,指针所有权转移给p2
unique_ptr<string> p3(new string(""));
p2.reset(p3.release()); // reset释放了p2原来指向的内存

weak_ptr

指向由一个shared_ptr管理的对象,将weak_ptr绑定到一个shared_ptr不会改变引用计数。

auto p = make_shared<int>(42);
weak_ptr<int> wp(p);
if (shared_ptr<int> np = wp.lock())     // 检查weak_ptr指向的对象是否存在
{
    // ...
}

动态数组

int *pia1 = new int[10]();     // 10个值初始化为0的int
int *pia2 = new int[10]{0,1,2,3,4,5,6,7,8,9};
delete [] pia1;

/* unique_ptr管理动态数组 */
unique_ptr<int[]> up(new int[10]);
up.release();   // 自动用delete[]销毁其指针

/* shared_ptr管理动态数组 */
/* 必须提供自定义的删除器 */
shared_ptr<int> sp(new int[10], [](int *p) {delete[] p;});
sp.reset();     // 使用自定义的lambda释放数组

allocator类

new将内存分配和对象构造组合在一起,当分配大块内存时,可能希望将内存分配和对象构造分离

使用allocator分配未初始化的内存,使用时再构造对象

allocator<string> alloc;
auto const p = alloc.allocate(n);   // 分配n个未初始化的string
auto q = p;
alloc.construct(q++, "abc");    // 构造对象
alloc.destroy(--q);     // 销毁对象
alloc.deallocate(p, n);     // 释放内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值