第十二章 动态内存
来源:互联网 发布:iptv服务器软件 编辑:程序博客网 时间:2024/05/17 09:30
程序除静态内存和栈内存,还有自由空间(free store)or 堆(heap)。
使用动态内存容易造成内存泄漏:忘记delete new分配的空间。
share_ptr类:模板。最好用make_shared函数来分配内存。
shared_ptr<int> p1 = make_shared<int> ();shared_ptr<string> p2 = make_shared<string> (6, '6');shared_ptr<int> p3(p1);//允许多个指针指向同一个对象,shared
refrence count:比较重要,变为0,自动销毁管理对象,释放相关内存。 拷贝递增,赋新值或销毁时递减,如局部shared_ptr离开其作用域。(注:将shared_ptr存入容器,而后不在需要全部元素,记得erase。)
类使用动态内存:1 不知道自己需要使用多少对象——容器类。 2 不知道对象准确类型。 3 多个对象间共享数据——类成员引用相同的底层数据,只有当引用计数为0时销毁底层数据。
释放一块非new分配内存或者同一内存释放多次,undefined。
然而释放一个空指针总没错:*p0 = nullptr; delete p; //OK
空悬指针(dangling pointer):delete之后,指针任然保存内存地址,即它指向一块曾经保存数据但现在已经无效的内存。最好: int *p = new int(666); delete p; p = nullptr; //指针置空
但是多指针指向同一内存时要多加小心。
shared_ptr<int> p1 = new int(666);//error:不能将内置指针隐式转换为智能指针shared_ptr<int> p2(new int(666)); //OK;直接初始化/*特别是在函数返回类型为智能指针时要注意*/shared_ptr<int> func1(int p){ return new int(p);} //wrong!shared_ptr<int> func2(int p){ return shared_ptr<int>(new int(p));}//OK!
void process(shared_ptr<int> ptr){ //使用ptr}/*当传递给该函数一个shared_ptr类型参数时,引用计数至少为2*/shared_ptr<int> p1(new int(666)); //引用计数1process(p1);//拷贝,函数中引用计数2,p1离开作用域销毁,变为1,并未释放内存,p1仍然指向分配的内存,可继续使用,注意后续处理。/*当传递给该函数一个内置指针时*/int *p2(new int(666));process(p2);//error:不能隐式转化process(shared_ptr<int>(p2));//OK,用完之后引用计数就为0了,内存已经释放!
使用get()时需注意,get()返回指针的代码不能delete此指针,否则原来的shared_ptr将变成空悬指针。不要用get()初始化或为另一个智能指针赋值。
reset():
if (!p.unique()) //检查我们是否是当前对象的唯一用户 p.reset(new int(*p));//不是,分配新的拷贝//现在是唯一用户,操作p
智能指针确保发生异常时的资源释放:
void func1(){ shared_ptr<int> p1(new int(666)); //抛出异常} //函数结束时,自动释放资源void func2(){ int *p2 = new int(666); //delete之前异常,不会释放资源 delete p2;}
使用智能指针管理的不是new分配的内存,要传递给它一个删除器:
shared_ptr<T> p(i, c);//c是执行析构操作的可调用对象,是我们自定义的删除器
unique_ptr不支持普通的拷贝或赋值操作,可以拷贝或赋值一个将要被销毁的unique_ptr,例如从函数返回一个unique_ptr。注意release()方法并未调用delete。
unique_ptr<int> p1 = new int(666);p1.release();//并未释放内存,不要这样用auto p = p1.release();delete p;//释放了内存
weak_ptr绑定到shared_ptr来观察对象,不改变引用计数,不能用来直接访问对象,因为有可能对象不存在,需调用lock()方法:
shared_ptr<int> p = new int(666);weak_ptr<int> wp(p);if (shared_ptr<int> p1 = wp.lock()){ //lock返回ture,才能进入if语句体通过p1对对象进行操作}
尽量使用标准库容器而不是动态分配的数组!
分配一个数组,得到的是一个数组元素类型的指针,并非一个数组类型的对象!
int *p = new int [num]();//最好初始化一下delete [] p;char arr[0] //error:不能定义长度为0的数组char *cp = new char[0]; //OK,动态分配一个空数组是合法的, //但不能解引用cp
unique_ptr<int[]> p(new int[10]);//unique_ptr直接管理动态数组p.release();//书上说这里会自动调用delete[],因为管理的是一个数组shared_ptr<int> p1(new int[10], [](int *p) {delete [] *p;}); //shared_ptr管理动态数组需传递一个删除器,没有定义[],智能指针不支持指针算术运算,get()内置指针来访问数组元素。
allocator类:分配原始的、未构造的内存,将分配内存与对象构造分离开来,提高灵活性。
allocator<string> alloc; //可以为string对象分配内存auto p = alloc.allocate(num); //分配num个string对象//construct()方法构造;//destroy()方法销毁;//deallocate()释放内存;先destroy再释放//相关算法,copy,fill;
- 第十二章 动态内存
- 第十二章 动态内存
- 第十二章 动态内存
- 第十二章 类和动态内存分配
- 第十二章 类和动态内存分配
- 第十二章 类和动态内存分配
- 第十二章:类和动态内存分配
- 第十二章 类和动态内存分配
- 第十二章-类和动态内存分配
- C++ Primer : 第十二章 : 动态内存之动态数组
- c++第十二章 -(动态管理内存、动态数组和函数返回动态内存)
- 【c++ primer】第十二章 类和动态内存分配
- 《c++ primer》第五版 第十二章 动态内存
- C++ Primer : 第十二章 : 动态内存之shared_ptr类
- C++ Primer : 第十二章 : 动态内存之unique_ptr和weak_ptr
- C++ Primer : 第十二章 : 动态内存之allocator类
- C++学习笔记【第二部分第十二章:动态内存】
- C++学习笔记【第二部分第十二章:动态内存】
- 放下你那屌屌的架子,学会聆听别人的想法---致那些傲慢的家伙
- (crm笔记2-4)表单数据删除后的页面跳转问题
- Android自定义View初识
- 2017中秋佳节记
- ES6(六: 函数扩展)(默认值,rest参数,扩展运算符)
- 第十二章 动态内存
- WPF and Silverlight 学习笔记(七):WPF布局管理之StackPanel、WrapPanel、DockPanel
- Jquery中AJAX参数详细介绍
- 图论中的双射
- BZOJ 2588 & SPOJ 10628:树上主席树
- Qt图片与Base64之间的编解码
- [Python]网络爬虫(二):利用urllib2通过指定的URL抓取网页内容
- java版云笔记(九)之动态sql
- 校招准备系列:每天一道算法题(12)-从尾到头打印链表