c++primer笔记----动态内存

  • 全局变量、局部变量、static变量的声明周期和动态分配的变量不同。动态分配的对象只有显式地被释放,才会销毁
  • 静态内存:保存局部static对象、类static数据成员以及定义在任何函数之外的变量。static对象在使用之前分配,在程序结束时销毁
  • 栈内存:保存定义在函数内的非static对象。仅在其定义的程序块运行时才存在
  • 堆或者自由空间:存储动态分配的对象

shared_ptr

//  
shared_ptr p1;  //保存着一个空指针

// make_shared(args)
shared_ptr p3 = make_shared(42);
shared_ptr p4 = make_shared(10, 'd');

//引用计数:拷贝,初始化,函数参数,函数返回值,计数+1 。销毁计数-1
auto r = make_shared(42);
r = q;  //q对象的引用计数+1,r指向对象的引用计数-1。所以,42被释放
  • 使用动态内存的原因:
  1. 程序不知道自己使用多少个对象。如vector
  2. 程序不知道所需对象的准确类型
  3. 程序需要多个对象间共享数据
  • 直接管理内存
int *pi = new int;  //pi指向一个动态分配、未初始化的无名对象。默认初始化
int *pi = new int(1024);  //值初始化
string *pi = new string; //默认初始化为空字符串
vector *pv = new vector{0,1,2};  //值初始化
int *pi = new int();  //值初始化0
string *pi = new string(); //值初始化为空字符串
  • 释放动态内存:释放一块并非new分配的内存,或者将相同的指针释放多次,其行为是未定义的
delete p;
  • 动态内存管理容易出错:忘记delete内存;使用已经释放掉的对象(记得将指针置为空,但保护有限,可能多个指针指向同一自由块);同一个内存块释放两次
  • shared_ptrnew结合使用
shared_ptr p1 = new int(42);  //error : explict
shared_ptr p2(new int(42));
  • 当将一个shared_ptr绑定到一个普通指针时,不应该再使用内置指针来访问所指向的内存了
  • p.get()将指针的访问权限传递给代码,但不能delete指针所指向的内存。不要用其初始化另一个智能指针
shared_ptr p1(new int(42));
int *q = p.get();  //使用q时注意,不要让它管理的指针被释放

p = new int(1024);
p.reset(new int(1024));
if(!p.unique())
    p.reset(new string(*p));
*p += newVal;
  • 智能指针和哑类。当类没有析构函数负责清理对象使用的资源时,可以利用shared_ptr。当使用智能指针管理的资源不是new分配的内存,传递给它一个删除器
void end_connection(connection *p) { disconnection(*p); }
connection c = connect(&d);
shared_ptr p(&c, end_connection);  //当p被销毁时,调用end_connection
  • unique_ptr
unique_ptr p1;
unique_ptr p12(3);

p2(p1.release());  //p1 = null ,p2控制p1的内存对象
p2.reset(p1.release());  //p1 = null, p2释放对象,并控制p1的对象

//不能拷贝的unique_ptr可以作为函数返回,进行拷贝
  • unique_ptr传递删除器
unique_ptr
    p(&c, end_connection);
  • weak_ptr:是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象
auto = = make_shared(42);
weak_ptr wp(p);

//由于对象可能不存在,不能使用wp直接访问对象,必须调用lock。如果存在,则返回指向共享对象的指针
if(shared_ptr np = wp.lock()){  如果np不为空则条件成立d
//在if中,np与p共享对象
}
```d

你可能感兴趣的:(c++primer笔记----动态内存)