Home Article C++内存管理

C++内存管理

Release time:2020-07-29 22:36:09 Author:一蓑烟雨 Reading volume:237
由于内存位稀缺资源,所以要进行内存管理。

Linux内存模型:


内存泄露的原因:
1.申请的内存没有释放
2.野指针
C语言的内存管理:
交给用户管理,靠良好的编程习惯

GC:垃圾回收机制,当申请的内存忘记回收会自动清理垃圾。

C++为什么没有垃圾回收机制:
1.C++没有共同基类(类似于0号进程)
2.垃圾回收带来额外的系统开销
3.导致性能的下降,消耗更多的内存
4.有替代方法

GC替代方法:析构,智能指针、引用计数
智能指针:
auto_ptr:C++98语法,过时
shared_ptr:
use_count() :返回有多少个shared_ptr智能指针指向某对象;(引用计数的个数)
unique():是否该智能指针独占某个对象,独占返回true,否则返回false;
reset():无参时,若独占对象,则释放对象并将指针置nullptr,不独占时,将应用计数减1并将指针置nullptr。有参数时,若独占,则 释放对象并置nullptr,不独占时将应用hu减一并指向新对象
#include <iostream>
#include <memory>
using namespace std;
class Test{
public:
Test(){
cout << "Test()" << endl;
}
~Test(){
cout << "~Test()" << endl;
}
friend ostream &operator<<(ostream &out , const Test &t){
out << "Test";
return out;
}
};
using namespace std;
int main(){
//shared_ptr
int num = 5; //C++11
shared_ptr<int> pi(new int (5));
int *p = new int(4);
shared_ptr<int> pi2(p);
//共享指针包裹
shared_ptr<Test> pt(new Test());
cout << *pi << endl;
cout << *pi2 << endl;
cout << *pt << endl; //C++14 推荐该方法,效率更高
shared_ptr<string> ps = std::make_shared<string>("hello world");
shared_ptr<int> pi3 = std::make_shared<int>(1);
return 0;
} shared_ptr<int> pi(new int (5));
shared_ptr<int> pi1 = pi; //裸指针int *
shared_ptr<int> pi2 = pi1;
cout << pi.use_count() << endl; //输出3
pi.reset();
if(pi == nullptr){
cout << "pui is null" << endl; //会执行
}
pi.reset(new int(6)); //重新指向新地址

//get():考虑到有些函数参数是裸指针并不是智能指针,所以需要将智能指针转化为裸指针;
int *p = pi.get(); //因为现在pi中存的是int。
//对于裸指针有时候要注意,例如下句会执行报错,程序默认裸指针为Test*而只调用一次析构函数。
shared_ptr<Test> pt(new Test[3]);
//修改:
shared_ptr<Test []> pt(new Test[3]); //指定删除器
void mydelete(Test *pa){
cout << "my delete" << endl;
delete [] pa;
} shared_ptr<Test> ps(new Test [3] , mydelete);
unique_ptr
独占式指针(专属所有权),同一时刻,只能有一个unique_ptr指向这个对象;当指针销毁,指向的对象也销毁;大小等于裸指针的大小。
初始化
手动初始化:unique_ptr<int> p;
或unique<int> p(new int(5));
std::make_unique函数(C++14) 注:生成的指针不支持指定删除器语法

unique_ptr常规操作
不支持操作:该指针不支持拷贝和赋值操作;所以函数传参必须传引用。
移动语义std::move();
release():放弃对指针的控制权,将该指针置nullptr,返回裸指针。
reset();
解引用:get():返回裸指针。
指定删除器
语法:unique_ptr<指向对象类型,删除器的类型> 智能指针变量名
自定义删除函数
lambda函数
decltype()
指定不同的删除器会导致不同的unique_ptr;

shared_ptr指定不同的删除器不会影响其类型;而unique_ptr 会。
比如定义一个vector存放,会发现不同删除器的指针不同都push_back()。
unique_ptr尺寸:和裸指针一样大,但是指定自定义删除函数会影响尺寸大小;

weak_ptr
一般用来辅助shared_ptr的使用,shared_ptr可以复制给weak_ptr,反过来不行,需要lock()
与shared_ptr的强引用不同的是,它是弱引用。
两者大小都是16(64位系统),因为本质是两个指针,一个指向对象,一个是指向控制块。
方法:
lock函数获得shared_ptr(若对象已经被释放,则返回空)
use_coputn():返回有多少个shared_ptr指向某对象
expired():判断弱指针是否过期(所检测的对象是否被释放 true/false)
reset():将该弱指针设置为空,弱引用计数减1,强引用计数不变
shared_ptr pi(new int (5));
weak_ptr pw = pi;
pi = pw.lock();
  
I want to comment

Search

classification

Leave a message
http://blog.rjxj513.com/index.php/
User login
You have not written any reviews yet!
You have commented!
Can only praise once!
You have a collection!