浅谈C语言和C++中的内存管理

面试题

内存管理了解多少,说出你知道的

C语言内存分配布局

进程在内存中的布局

最高内存地址

      栈区(函数内部的局部变量,自动释放 )
  堆栈增长区
      堆区(动态内存分配,由程序员申请释放)
    其他段
    .bss段(未初始化的全局变量)
   .data段(也叫数据段,已经初始化的全局变量)
   .text段(文本段,进程所执行程序的二进制文件)

最低内存地址       

C++内存分配布局       

  1. 栈区—函数内局部变量和函数参数的存储空间,由编译器自动释放
  2. 堆区——动态分配内存(malloc)
  3. 自由存储区——C++根据new定义的抽象的概念,new在这上面分配内存
  4. 全局/静态变量区——全局变量和静态变量存放在这里,和C不同初始化和未初始化的全局变量都放在一起
  5. 常量存储区——存放常量,只读         

引申堆栈的区别以及malloc/free和new/delete的区别

控制内存分配——频繁地调用new/delete(malloc/free)会导致内存碎片化,引发堆破碎等问题,所以要管理内存的分配

防止堆破碎的通用方法是从不同固定大小的内存池中分配不同类型的对象,对每个类重载new/delete就提供了这样的控制。

重载new/delete,为什么要重载,两种方式:1.重载全局new/delete 2.为每个类重载new[]/delete[]

原因:系统为我们提供的默认的new/delete操作符,缺乏对具体对象的具体分析。系统提供的分配器无论是时间还是空间都存在不足:分配器速度较慢,在分配小型对象时空间浪费严重,特别是在一些对效率或内存有较大限制的特殊应用中。比如说在嵌入式的系统中,频繁地进行不定大小的内存动态分配很可能会引起严重问题,甚至出现堆破碎的风险。再比如在游戏设计中,效率绝对是一个必须要考虑的问题,而标准new与delete操作符的实现却存在着天生的效率缺陷。此时,我们可以求助于new与delete操作符的重载,它们给程序带来更灵活的内存分配控制。

重载new/delete的好处:

     a)改善效率

     b)检测代码中的内存错误

     c)性能优化 

     d)获得内存使用的统计数据

 内存管理基本要求  ——不重不漏,不重复delete,不遗漏delete。new/delete要匹配成对出现,这里的匹配不只是数量,调用本身也要匹配,不同类的new和delete不可混淆使用,不能出现“借了东家的东西西家换”的情况。

常见的内存错误和解决方法

  1. 内存分配未成功,就使用了它。在编程初期经常会出现这种问题,因为没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。
  2. 内存分配成功但未初始化,就使用它。犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。 内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。
  3. 内存分配成功也初始化了,但是在使用时操作越界。例如使用数组时发生的“多1”“少1”的操作,特别的在for循环中,要注意循环次数,防止越界。
  4. 忘记释放内存,导致内存泄漏。这种错误在一开始并不会对程序的运行造成什么影响,因为此时内存充足,但是每次这个函数调用的时候,都会占用一块内存不去释放,终会有内存耗尽的时候,这个时候程序就死掉了。所以必须配对,使用次数要相同。
  5. 释放了内存却继续使用它。有三种情况:(a)程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。(b)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。(c)使用free或delete释放了内存后,没有将指针设为NULL,形成野指针,后面调用这种指针。

常见的内存错误对策如下:

【规则1】用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。

【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。

【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。 

【规则4】动态内存的申请与释放必须配对,防止内存泄漏。

【规则5】用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值