范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

C堆,栈,RAII

  堆 英文名称 heap,在内存管理的语境下,指的是动态分配的内存空间,这个和数据结构的堆是两回事。
  这里的内存,被分配之后需要手动释放,否则会引发内存泄漏。
  那怎么申请一个堆内存空间呢?
  C语言中使用 void* malloc(size_t size)  来申请一块内存空间,size为申请的字节数。 使用 void free(void* ptr)   来手动释放内存。
  C++则使用  new   和  delete   来申请释放内存。
  C++标准里有一个相关概念是自由存储区,英文是free store,特指使用 new 和 delete 来分配和释放内存的区域。 一般而言,这是堆的一个子集。
  为什么有了 malloc, free, C++中还出现了 new, delete 呢?
  实际上 new, delete 的底层实现是 malloc, free;malloc 只是单纯地申请一块内存空间,但是new不一样,C++中包含面向对象的设计,当我们在new一个对象时,C++不仅要向系统申请一块内存,还需要构造这个对象,调用构造函数,而delete时,则需要调用类的析构函数,然后归还内存空间。
  实际上new的操作类似于这样: T* p; void* mem = operator new(sizeof(T));  // 分配内存,其内部调用malloc try {     p = static_cast(mem);  // 类型转换     p->T::T( ... );  // 调用构造函数     return p; } catch ( ... ){     operator delete(p);     throw; }
  如果申请内存成功,并且调用构造函数正常,则对象构造成功,否则释放申请的内存, 抛出  bad_alloc   异常。
  而 delete 的操作类似于这样: p->T::~T();  // 调用析构函数 operator delete(p);  // 释放内存,内部调用 free
  先调用析构函数,再释放内存,如果反过来,先释放内存就没办法调用析构函数了嘛? 是不是?
  栈  英文名称 stack, 在内存管理的语境下,指的是函数调用过程中产生的本地变量和调用数据的区域。 这个栈和数据结构里的栈高度相似,都满足后进先出(last-in-first-out 或 LIFO)。
  我们先来看一段示例代码,来说明 C++ 里函数调用、本地变量是如何使用栈的。当然,这一过程取决于计算机的实际架构,具体细节可能有所不同,但原理上都是相通的,都会使用一个后进先出的结构。 void foo(int n) {  } void bar(int n){     int a = n + 1;     foo(a); } int main(){     bar(42); }
  生长方向: 栈是朝着地址减小的方向生长的,而堆是朝着地址增大的方向生长的。
  当函数调用另外一个函数时,会把参数也压入栈里然后把下一行汇编指令的地址压入栈,并跳转到新的函数。 新的函数进入后,首先做一些必须的保存工作,然后会调整栈指针,分配出本地变量所需的空间,随后执行函数中的代码,并在执行完毕之后,根据调用者压入栈的地址,返回到调用者未执行的代码中继续执行。
  本地变量就保存在栈上,当函数执行完成之后,保存本地变量的栈内存就被释放掉了。
  上述例子中本地变量是内置的类型,本地变量不光可以是内置的类型,还可以是复杂的类型,比如说类的对象,这时,如果 函数调用结束之后或者发生异常时 ,编译器会自动调用类的析构函数,这个过程叫做 栈展开(stack unwinding) 。
  例如: class A { public:     A() { cout << "A" << endl; }     ~A() { cout << "~A" << endl; } };  int main() {     try {         A a;         throw "error";     }     catch (const char* s) {         cout << s << endl;     }     return 0; }
  由于函数调用栈的是先进后出的执行过程,在某一个栈空间被弹出时,在它上面后进的空间一定已经被弹出了,不可能出现内存碎片。
  另外, 图中每种颜色都表示某个函数占用的栈空间。 这部分空间有个特定的术语,叫做 栈帧(stack frame) 。
  RAII
  上面讲了堆和栈,堆只要正确的使用 new和 delete 也不会造成内存溢出,但是这是比较难的,各种情况都会有意无意 的 导致内存泄漏。 比如: // 1 A* p = new A; ...             // 这一大段代码抛异常了,delete没有被执行 delete p;// 2,分配和释放不在同一个函数内 A* create_A() {     A* p = new A;     return p; }  void f() {     A* p = create_A();     ...  // 中间代码一长就很可能漏掉     delete p; }// 3. 返回子对象的坑 class A { public:     A() {}     ~A() {} private:     int m_a; };  class B : public A { private:     int m_b; };  A create() {     B b;     return b; }
  create 函数返回父类A的对象,实际上函数内返回的是子类B,编译器不会报错,但是多半是不对的,这种现象称为对象切片,把子类包含的数据成员给切掉了。 正确的我们应该返回 pointer  或 pointer like class  。
  下面引出我们的主角RAII,RAII (Resource Acquisition Is Initialization),字面意思,资源获取即初始化。
  RAII 其实是为了解决上述忘记delete引发的内存泄漏问题而出现的,我们只需要把要返回的内容封装成类的对象成员,而这个类的对象就是一个本地变量,而本地变量是在栈上的,当对象离开它的作用域后将自动调用析构函数,我们只需要在析构函数内释放堆内存空间就可以了。 class A { public:     A(int a = 1) : m_a(a) {}     ~A() {}     int m_a; };  class Wrapper { public:     Wrapper(A* pa = NULL) : ptr(pa) {}     ~Wrapper() {         delete ptr;         cout << "~Wrapper" << endl;     }     A* get() const { return ptr; }  private:     A* ptr; };   Wrapper create() {     return Wrapper(new A); }   int main() {     Wrapper w_ptr = create();     cout << w_ptr.get()->m_a << endl;     return 0; }// 输出 1 "~Wrapper"
  这里只是做一个简单的实例,其实可以把它写成  pointer like class  ,让  w_ptr  更像一个指针。
  总的来说,资源在构造函数内获得,在析构函数内释放,实例对象是在栈上的本地变量。
  RAII通常可以用来: 关闭文件释放互斥锁释放其他的系统资源。
  好了, 堆 ,栈,RAII先说到这里了,如果文章有错误的地方还请给我指出来,大家一起进步嘛。
  如果觉得对你有帮助的话请@程序员杨小哥 点个赞,谢谢!

85。99万!宝马X5PHEV动力和油耗兼顾,搭载激光大灯,5。6S破百现在全球的消费者越来越接纳新能源汽车了,新能源汽车全面到来仿佛只是一个时间的问题。作为传统的燃油车企,宝马做出怎样的表现呢?在去年的11月份,宝马X5的新能源汽车上市了,很多小伙伴卖完不再补货!新款发布,老款iPadAir开启清仓256GB价格太香了来了,一年只有两次机会的苹果捡漏款来了!众所周知,苹果的产品老款的才是最香的,一是苹果产品非常耐用,性能强劲,而且可以坚持好多年,要不然苹果也不会还在卖iPhone11iPhone手机出货量暴跌00后4年没换手机为何人们换手机的动力下降了?据媒体报道,今年2月中国手机出货量就大跌了三成多,消费者换手机的动力也越发下降了。一位00后大学生,她现在用的苹果手机还是四年前买的,当时花了七千多元。四年来她从没想过换手机,即便2月最新国内手机销量排名出炉!小米排第5最近,市场调研机构CINNOResearch发布了最新的2022年2月中国智能手机销量数据报告。根据这份报告,首先在市场总体方面,2月中国市场智能手机销量约2348万部,同比下滑了太丢中国人的脸了!苹果销量猛增46,华为却跌出前五真的太丢中国人的脸了。前两天在网上看到了一些这样的评论,到底发生了什么事儿能让网友说出这么难听的话。十月份的时候苹果的销量猛增46,时隔六年之后再一次登顶中国市场,而华为却跌出了前手机销量暴跌三成,为何年轻人都不爱换手机了?原因无非就这几点手机销量暴跌三成,为何年轻人都不爱换手机了?原因无非就这几点近日,你有多久没有换手机了?,年轻人为什么不爱换手机了的话题登上热搜,引起网友们热烈讨论。有网友表示自己赚钱的速度赶不上滴滴打车竟然遇到摩托车接单乘车人很淡定近日网上流传出一段视频显示,一位滴滴打车车主采用摩托车接单成功并将乘客送往了目的地。从视频中来看,该车主驾驶的是一辆油电混动的摩托车,在充电结束后直接打开滴滴进行接单并成功接单了。为什么大疆无人机会成为俄乌冲突的焦点云哨成为科技不可预见的又一例证。来源TheVerge随着俄乌冲突愈演愈烈,许多公司被动卷入其中,原本的生意和立场,甚至技术本身都变得复杂起来。当地时间3月16日,大疆AeroSco还买啥特斯拉Model3?全新纯电超长轴宝马3系上市续航526公里今天说的这款车就是国产全新宝马i3。国产全新宝马i3昨晚惊喜上市,新车指导价格为34。99万元。虽然新车名字还是叫宝马i3,但是如今这款车,已经变成了电动版的超长轴宝马3系,更具市巩俐代言的安吉尔这个品牌怎么样?为什么这么多名人推荐安吉尔大家有没有感受到,虽然我们的生活变得好了,但是依旧有很多地方不如从前了,就比如水质。以前家里可以直接从井里打水,现在自来水都不敢随意喝。究其原因,那就是水质变差了。所以现在很多家庭能否成为骨传导耳机领域的搅局者?HaylouBC01骨传导耳机使用体验可能大家最近都关注到了,通过短视频的助推,全民健身空前火爆,越来越多的人开始参与到运动中来。很多人会注意到这些运动爱好者,特别是跑步爱好者通常会佩戴一款特别的装备挂在耳朵上。其实这
有哪些非常实用的录音转文字方法?我相信很多人不知道如何将录音转换为文本,但也有很多人想要一种快速将录音转换为文本的方法。毕竟,生活和工作的节奏是如此之快。如果有一个工具可以快速将录音转换为文本,它可以帮助我们提高刘强东汶川地震我把家底都捐了,一共10几万,而京东正面临破产刘强东,京东集团创始人,近日被曝出捐款150亿人民币的股票用于慈善,这对于国内众多企业来说,堪称大手笔,足以令人惊讶万分。其实京东集团在创立和成长过程中,也是历尽坎坷,甚至一度面临rustVec及struct结构体的相互转化derive(Debug,Clone)structRectanglexi32,yi32,implRectanglefnarea(self)i32self。xself。yfnperi再增10!山东省级科技创新发展资金达145亿鲁网2月22日讯(记者刘宗尧)今日山东省人民政府新闻办公室召开新闻发布会,介绍加快科技研发创新,充分释放科技研发新活力有关情况。据了解,山东省科技厅牵头,会同相关部门研究起草了科技中国移动联通电信发布重要公告5G用户数大涨通信1中国移动联通电信发布重要公告5G用户数大涨2月21日晚间,中国三大运营商中移动联通及电信发布重要公告,披露了2022年1月份的主要运营数据,5G用户数大涨。中移动表示,202很古老的液晶电视上门维修一个客户打电话维修一台液晶电视,询问电视几年了,客户说十多年。十多年前电应该是LCD液晶。进入客户家,发现果然十多年电视,色调还好,屏边缘稍稍发黑,但不细看看不出来,灯管稍微老化,ZEEKR001XYAMAHA剧院版音响体验ZEEKRXYAMAHA创新理念百年经验的完美对撞Yamaha通过品牌理念MakeWaves,捕捉用户们在音乐中感到兴奋的时刻它是一家能够激发用户热情,同时表达自身个性情感与创造力在黑屋中观看投影仪会对眼睛产生伤害吗?投影仪是通过投射光束到白墙或幕布后经过漫反射的形式成像,相对于电视机光直接照射在眼睛上的形式来说,对眼睛的伤害会比较小。但要注意,是相对,不是绝对。这也说明了长时间使用投影仪观看电东数西算产业链介绍自认为对该行业了解还可以的我,因为雪球访谈,我翻看了云计算数据中心全行业今天的表现涨停或涨幅超过10的超过40家,上涨超过4的超过110家,相关企业200家左右。相关企业太多,我不腾讯旗下小鹅拼拼即将关停墨茉点心局否认裁员腾讯旗下的重要电商业务小鹅拼拼即将关停今日,腾讯旗下的重要电商业务小鹅拼拼即将关停。同时,腾讯方面回应称,基于战略聚焦考量,PCG对内部孵化的新业务小鹅拼拼进行调整,相关团队将可通2022。02。22科技新闻生活很慢,世界很快2022。02。22科技新闻生活很慢,世界很快豌豆姑娘整理更多内容(豌豆壳外)1哪吒汽车完成超20亿元新融资,计划今年启动上市2快手签下欧冠版权(从2020年开始,快手体育签约各大