动态内存与智能指针
来源:互联网 发布:被淘宝托管骗了怎么办 编辑:程序博客网 时间:2024/05/18 13:28
1. 内存简单分类
静态内存:保存局部static对象、类static数据成员、在任何函数之外定义的变量;由编译器自动创建与销毁。
栈内存: 保存定义在函数内的非static对象;仅在定义的程序块运行时才存在。
堆内存: 保存那那些程序运行时分配的动态对象,动态对象的生存期由程序来控制;由程序代码显式地销毁。
2. share_ptr指针
初始化
调用make_shared函数初始化:make_shared(args)
e.g :
shared_ptr<int> p = make_shared<int>(); auto p1 = make_shared<int>();
使用new操作符初始化:shared_ptr<int> p2 (new int(42));
注:必须显示初始化智能指针;
拷贝与赋值
e.g:
p = p1;auto p(p1);
每个shared_ptr有一个关联的计数器(引用计数);
拷贝时,计数器递增,常见的拷贝情形有:
(1) 一个shared_ptr初始化另外一个shared_ptr时;
(2) 将shared_ptr传递给一个函数;
(3) 作为函数的返回值;
当一个shared_ptr对象的计数器值为0时,自动释放自己所管理的对象;
计数器递减的常见情形:
(1)给一个shared_ptr赋予一个新值;
(2)shared_ptr被销毁时,例如离开其作用域;
e.g
auto r = make_shared<int>(42);r = q; //给r赋值,令它指向另外一个地址; //递增q的引用计数 //递减r原来的所指的对象的引用计数 //r原来窒息那个的对象已没有引用,则会自动释放
改变shared_ptr的操作
3.直接管理内存
c++语言定义了两个运算符来分配和释放内存,运算符new分配内存,delete负责释放分配的内存。
若使用直接管理内存的类,不能依赖类对象拷贝、复制、销毁操作的编译器所设置任何默认定义。
3.1 new分配动态内存
初始化
(1)默认初始化:默认情况下为默认初始化,内置类型或组合类型的对象值将是未定义的,类类型则使用默认构造函数进行初始化;
(2)直接初始化:传统初始化(圆括号),列表初始化(花括号);
(3)值初始化:类型名后面加一对空括号;
(4)使用auto推断:提供一个括号包围的初始化器,只接受单一初始化器;
e.g:
int *pi = new int; //默认初始化int *ps = new string(10,'9'); //圆括号直接初始化vector <int> *pv = new vector<int> {1,2,3,4};//花括号列表初始化int *pi1 = new int(); //值初始化auto p1 = new auto (obj) //使用auto 初始化器
3.2 delete释放动态内存
动态对象生存期为知道被释放为止,必须通过delete释放动态内存。
使用delete释放动态内存时,编译器不能分辨一个指正指向的是静态还是动态分配的对象。
3.2.1 直接管理内存容易引起的常见问题:
(1) 忘记delete内存,导致内存泄露;
(2) 使用已经释放掉的对象;释放内存后将指针置为空,或许可以避免;
(3) 同一块内存释放两次。
3.2.2 使用普通指针与智能注意
混合使用普通指针和智能指针很危险!
考虑下面的代码:
void process (shared_ptr<int> ptr){ //使用ptr}//ptr离开作用域,被销毁
若正常传递一个shared_ptr
指针:
(1)调用该函数时,process的参数是指传递,实参会被拷贝给ptr
,
(2)递增其引用数,因此引用计数值至少为2,当process结束后局部变量ptr
销毁,但ptr
指向的内存不会被释放。
若传递一个普通指针如下:
int main(){ int *iptr = new int(42); process(shared_ptr<int>(iptr)); *iptr = 233;//error}
**注:**iptr拷贝给一个临时的shared_ptr
,该智能指针计数器为1,当结束process
函数时,临时的智能指针销毁,释放内存,因为与iptr
指向的内存相同;iptr
也会失效,使用iptr
指针将会产生错误。
正确做法:
share_ptr<int> iptr(new int 42);//计数值:1process(iptr); //拷贝,计数值递增:2 //离开函数,计数值:1*iptr = 233; //安全
不要使用get初始化另外一个智能指针或赋值
3. unique_ptr指针
初始化
unique_ptr 没有类似make_shared的标准库函数返回指针,故:
unique_ptr<int> p2(new int(42));//直接初始化
拷贝与赋值
unique_ptr不支持普通的拷贝或赋值;
但通过release或reset指针可以从一个(非const)unique_ptr转移给另外一个unique:
unique<int> p1 (new int (42));unique<int> p2 (p2.release());//release将所有权转移给p2,并将p1置空unique_ptr<int> p3 (new int(233));p2.reset(p3.release());//reset释放了原来p2的指向的内存
不能拷贝的一个例外:可以拷贝一个将要销毁的unique_ptr值。
e.g: 从函数返回一个unique_ptr
unique_ptr<int> clone(int p){ return unique_ptr<int> (new int(p));}
传递删除器
e.g unique_ptr<T,d> u(d)
4. weak_ptr指针
weak_ptr指针一种不控制所指对象生存期的智能指针,指向一个shared_ptr管理的对象,即绑定给一个shared_ptr不会改变shared_ptr的引用计数。
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- C++中的动态内存与智能指针
- C++中的动态内存与智能指针
- C++中的动态内存与智能指针
- (十二)动态内存与智能指针
- C++中的动态内存与智能指针
- C++中的动态内存与智能指针
- C++中的动态内存与智能指针
- hdoj 2222 Keywords Search 【字典树挤进1ms----啊--我要学AC自动机】
- C++ 顺序容器
- [又值奥运季] 2016年里约奥运会--8月16日赛事
- 在iOS端使用AVSampleBufferDisplayLayer进行视频渲染
- 微软面试百题007——链表相交
- 动态内存与智能指针
- 大学两年的总结与感悟
- MATLAB 读取多个子文件夹下相同格式的文件
- python 计算两个时间的月差代码
- android跨应用发广播
- Android学习笔记042之事件处理机制
- 给未来程序员的15个顶级职业建议
- 经常使用的 第三方
- 版本更新