- 全局变量、局部变量、
static
变量的声明周期和动态分配的变量不同。动态分配的对象只有显式地被释放,才会销毁
- 静态内存:保存局部
static
对象、类static
数据成员以及定义在任何函数之外的变量。static
对象在使用之前分配,在程序结束时销毁
- 栈内存:保存定义在函数内的非
static
对象。仅在其定义的程序块运行时才存在
- 堆或者自由空间:存储动态分配的对象
shared_ptr
类
// <memory>
shared_ptr<string> p1; //保存着一个空指针
// make_shared<T>(args)
shared_ptr<int> p3 = make_shared<int>(42);
shared_ptr<string> p4 = make_shared<string>(10, 'd');
//引用计数:拷贝,初始化,函数参数,函数返回值,计数+1 。销毁计数-1
auto r = make_shared<int>(42);
r = q; //q对象的引用计数+1,r指向对象的引用计数-1。所以,42被释放
- 程序不知道自己使用多少个对象。如vector<int>
- 程序不知道所需对象的准确类型
- 程序需要多个对象间共享数据
int *pi = new int; //pi指向一个动态分配、未初始化的无名对象。默认初始化
int *pi = new int(1024); //值初始化
string *pi = new string; //默认初始化为空字符串
vector<int> *pv = new vector<int>{0,1,2}; //值初始化
int *pi = new int(); //值初始化0
string *pi = new string(); //值初始化为空字符串
- 释放动态内存:释放一块并非
new
分配的内存,或者将相同的指针释放多次,其行为是未定义的
delete p;
- 动态内存管理容易出错:忘记
delete
内存;使用已经释放掉的对象(记得将指针置为空,但保护有限,可能多个指针指向同一自由块);同一个内存块释放两次
-
shared_ptr
和new
结合使用
shared_ptr<int> p1 = new int(42); //error : explict
shared_ptr<int> p2(new int(42));
- 当将一个
shared_ptr
绑定到一个普通指针时,不应该再使用内置指针来访问所指向的内存了
-
p.get()
将指针的访问权限传递给代码,但不能delete
指针所指向的内存。不要用其初始化另一个智能指针
shared_ptr<int> 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<connection> p(&c, end_connection); //当p被销毁时,调用end_connection
unique_ptr<int> p1;
unique_ptr<int> p12(3);
p2(p1.release()); //p1 = null ,p2控制p1的内存对象
p2.reset(p1.release()); //p1 = null, p2释放对象,并控制p1的对象
//不能拷贝的unique_ptr可以作为函数返回,进行拷贝
unique_ptr<connection, decltype(end_connection)*>
p(&c, end_connection);
-
weak_ptr
:是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr
管理的对象
auto = = make_shared<int>(42);
weak_ptr<int> wp(p);
//由于对象可能不存在,不能使用wp直接访问对象,必须调用lock。如果存在,则返回指向共享对象的指针
if(shared_ptr<int> np = wp.lock()){ 如果np不为空则条件成立d
//在if中,np与p共享对象
}
```d
网友评论