【C++】内存的那些事儿

前言:

     前两天看了个一句话特别的有意思,说为什么C++的书会比C语言的书厚那么多呢?答案很有意思,有了对象就会麻烦,虽然是个笑话,但是可以从中学到C++是一种面向对象的编程语言,从VB到C语言在到C++这是编程界一个质的飞越。通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类。让我们的编程更加容易。在计算机界这些对象存放在哪里呢?这就是我们今天要说的内存。

    1、内存的分配方式

     在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
     ①栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
     ②堆:从堆上分配,亦称动态内存分配。就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。使用非常灵活,但问题也最多。
     ③自由存储区:就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
     ④ 全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
      ⑤常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

    2、内存使用错误    

       * 内存分配未成功,却使用了它。
  在使用内存之前检查指针是否为NULL。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。
  * 内存分配虽然成功,但是尚未初始化就引用它。
  犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值
错误(例如数组)。 内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不
可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。
  * 内存分配成功并且已经初始化,但操作越过了内存的边界。
  例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞
错,导致数组操作越界。
  * 忘记了释放内存,造成内存泄露。
  含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次
程序突然死掉,系统出现提示:内存耗尽。
  动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误

     3 栈和堆的对比   

    从以上介绍中,它们有如下区别:
(1)栈是系统提供的功能,特点是快速高效,缺点是由限制,数据不灵活;
       堆是函数库提供的功能,特点是灵活方便,数据适应面广,但是效率有一定降低。
(2)栈是系统数据结构,对于进程/线程是唯一的;
       堆是函数库内部数据结构,不一定唯一,不同堆分配的内存无法互相操作。
(3)栈空间分静态分配和动态分配,一般由编译器完成静态分配,自动释放,栈的动态分配是不被鼓励的;
       堆得分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。
(4)碎片问题
    对于堆来讲,频繁的new/delete等操作势必会造成内存空间的不连续,从而造成大量的碎片,使程序的效率降低;对于栈来讲,则不会存在这个问题,因为栈是后进先出(LIFO)的队列。
(5)生长方向
    堆的生长方向是向上的,也就是向这内存地址增加的方向;对于栈来讲,生长方向却是向下的,是向着内存地址减少的方向增长。
(6)分配方式
      堆都是动态分配的,没有静态分配的堆;
      栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配则由alloca函数进行分配,但是栈的动态分配和堆不同,它的动态分配是由编译器进行释放,无需我们手工实现。

        

    小结: 通过学习C++对面向对象的思想有了更加深入的理解,灵活自由是C++语言的一大特色,但也是一个大难题。当程序越来越复杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问 题。内存泄漏是最常见的内存问题之一。内存泄漏如果不是很严重,在短时间内对程序不会有太大的影响,这也使得内存泄漏问题有很强的隐蔽性,不容易被发现。 然而不管内存泄露多么轻微,当程序长时间运行时,其破坏力是惊人的,从性能下降到内存耗尽,甚至会影响到其他程序的正常运行。所以学好C++就必须管理好内存啊。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值