首页 > 编程知识 正文

资源管理器管理文件的方式是,信息资源管理的一般方式

时间:2023-05-04 09:13:35 阅读:229719 作者:1810

堆,栈和RALL:C++管理资源的方式

一、堆(heap)
1.由程序员动态分配,底层由malloc和free进行管理
2.同样的使用new关键字也在堆上分配内存,但并不是每一次new都会调用底层的malloc方法,因为有着内存池的存在
3.在函数中如果非必需,不然不要使用堆内存

void buzz() {vector<int> *p = new vector<int>(100);...... delete p;}

上述代码这么写是有问题的,如果在…函数操作的时候代码抛出了一样,将会导致后面的delete p无法执行,从而导致了内存泄漏
4.在绝大部分情况,由一个函数于堆中申请内存,然后在另一个函数中释放申请的内存,但如此一来程序员就会大大的忘记释放的内存的操作,所以C++提供了RALL来帮助程序员更好的管理内存,可以认为这就是一个简易版的GC
5.释放内存的常见错误

Buzz *p = new Buzz[1024];delete p;

上述代码所示,delete p将会完整的释放malloc所申请的堆内存,但是编译器并不知道指针p是单个对象还是多个对象组成的数组,而delete p 明确告诉编译器指针p是单个对象,所以,只会调用一次Buzz对象的析构函数,从而导致内存泄漏
正确的做法是delete[] p,从而告诉编译器p是一个由多个对象所组成的数组,在释放堆内存的同时,应该调用1024次对象的析构函数

二丶栈(stack)
1.栈由栈帧所组成,函数参数,函数局部变量等内容均在栈帧中保存
2.栈内存由于FILO的特性,将使得栈内存不可能出现内存碎片的现象,这也是栈内存的效率比堆内存效率高的原因之一,堆内存在绝大多数情况下都会出现内存碎片
3.简而言之,在栈中分配的对象编译器会在合适的地方插入对构造函数和析构函数的调用,并且在抛出异常的情况下,对象的析构函数也会被调用(栈展开)
4.在栈中分配的对象有一个很重要的特性,即系统会自动地在合适的地方插入对其构造函数和析构函数的调用

三、RALL(Resource Acquisition Is Initialization)
C++所特有的资源管理方式,使得C++本身并不需要实现GC就可以很好的进行内存管理
RALL有两大组成部分:栈和析构函数

class Buzz {public: Buzz() { puts("constructor"); } ~Buzz() { puts("destructor"); }};class BuzzWrapper {private: Buzz* ptr;public: BuzzWrapper(Buzz* p) : ptr(p) {} ~BuzzWrapper() { delete ptr; } Buzz* get() const { return ptr; }};void foo() { BuzzWrapper wrapper = BuzzWrapper( new Buzz());}

当foo函数返回时,不管有没有异常的发生,都会自动调用wrapper对象的析构函数,而该析构函数中又释放掉了从堆中申请的内存,从而达到了正确释放内存的目的
再有了BuzzWrapper类以后,我们就可以将堆内存中对象的释放交给它,无需担心因忘记delete对象从而导致内存泄露的问题了
这其实就是C++智能指针的一个基本雏形了,当然了,他不是一个模板,所以只能作用在Buzz类及其派生类上,并且功能非常的单一

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。