标签:忘记 参考 names 单元 div sys ++ 动态分配 释放内存
由于在c++中我们可以动态分配内存,但有时候我们会忘记用
delete或free释放内存,就会导致内存泄露。所以c++11提供了智能指针这种东西
本文参考了知乎某知乎友的
https://www.zhihu.com/people/mo-shan-zhe/activities
比如下面这两种情况
//1 内存泄漏 str1所指的资源没有被释放 { string* str1 = new string("hello"); string* str2 = new string("world"); } //2 多重释放,引起程序崩溃 { string* str1 = new string("hello"); delete str1; //... delete str1;//引起程序崩溃 }
可能平时都写在一个文件不会忘记释放内存,但如果是一个大的项目就出问题了
然后是智能指针的赋值方式和普通指针有差异
可以在定义时就可以动态分配内存单元,但不允许先定义智能指针,再为其动态分配内存空间
再然后普通指针和智能指针之间的赋值也得很注意,
不能把智能指针指向普通内存变量,或者把非智能指针赋值给智能指针。
但可以把智能指针赋值给普通指针,但不是那么直接,需要通过智能指针的get()成员函数获取智能指针中的指针后
再赋值给普通指针
1.先说一下auto_prt是c++98标准定义的独占智能指针,这意味着
一个对象只能被一个auto_prt指向,两个同类型的auto_ptr不能指向同一个对象
指针的赋值或复制操作会改变对象所有权,被复制的auto_prt不再指向任何对象
#include<iostream> #include<memory> #include<string> using namespace std; int main() { auto_ptr<string> p1(new string("hello world!")); auto_ptr<string> p2; p2 = p1;//p1不再指向任何对象,其所指对象被p2指向了 //cout << *p1;//错误代码,因为p1不指向任何对象 cout << *p2 << endl; //p1 = new string("hello")不能用这种方式给智能指针赋值 auto_ptr<string> p3(p2); //p2不再指向任何对象,其所指对象被p3指向了 cout << *p3 << endl; //cout << *p2 << endl;//错误代码,因为p1不指向任何对象 return 0; }
运行是会有警告,
因为c++11不推荐使用auto_ptr,提出了unique_ptr来代替,用途和auto_ptr相同
但c++11禁止unique_ptr之间的赋值,也不允许使用一个unique_ptr初始化其他指针,否则会出现编译错误
比如
int main() { unique_ptr<string> p1(new string("hello world!")); unique_ptr<string> p2; p2 = p1;//错误 unique_ptr<string> p3(p1);//错误 //system("pause"); return 0; }
下面再来说shared_ptr
它是一种共享指针,也就是说多个指针可以同时指向一个对象。
c++11允许shared_ptr指针之间的赋值,也允许使用一个智能指针初始化其他指针
再看原理分析
1.当从堆上申请了一个资源时,我们就创建一个智能指针对象,使它指向这个资源,同时,
在堆上申请一个用于计数的资源,让后来所有的指向该资源的对象都共享这个计数资源,这样,引用计数的个数就只有一份。
2.当将ptr1对象赋值给对象ptr2时,其共享的引用计数变为2。
3.删除ptr2对象时,其对应的引用计数减为1。
4.删除ptr1对象时,引用计数变为0,则释放资源。
首先,智能指针是一个类,这样就可以使用构造函数和析构函数对引用计数进行维护;
其次,它要表现出指针的行为,并且使用起来也要像普通指针一样;
最后,智能指针对任何类型都可以使用,所以它应该是一个模板。
具体实现看知乎原文吧
我们看一个应用例子把,实现两个数交换
#include<iostream> #include<memory> using namespace std; void swap(shared_ptr<int> a,shared_ptr<int> b) { int t; t = *a; *a = *b; *b = t; } int main() { shared_ptr<int> p1(new int(9)); shared_ptr<int> p2 = p1; shared_ptr<int> p3(new(int)),p4(new int(8)),p5; cout << "p1 = " << *p1 << "\tp4 = " << *p4 << endl; swap(p1,p4); cout << "p1 = " << *p1 << "\tp4 = " << *p4 << endl; p3 = p4 = p5 = p1; cout << *p1 << "\t" << *p2 << "\t" << *p3 << "\t" << *p4 << "\t" << *p5 << endl; return 0; }
上面的代码我们多次用了new动态分配内存空间,但我们并没有delete过,
由于shared_ptr的存在,它会自动回收,就不会造成内存泄露
同时c++11还提供了一个配合shared_ptr使用的弱智能指针weak_ptr,
用于解决两个shared_ptr指针应用之间的循环计数问题。这个我不敢看了后面再补吧
标签:忘记 参考 names 单元 div sys ++ 动态分配 释放内存
原文地址:https://www.cnblogs.com/mch5201314/p/11687609.html