关闭

C/C++程序的内存分配与使用笔记

发表于:2014-8-22 10:14

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:tiany524    来源:51Testing软件测试网采编

  实例共8个变量,包括一个全局变量g_nGlobal,1个局部静态变量nLocalStatic、以及6个局部变量。
  在Windows XP 中使用VC2008编译运行,程序出处如下:
globalvariable:0x417000
staticvariable:0x417148
localprinter1:0x4158fc
localconstprinter:0x4158ec
new:0x383248
malloc:0x383288
localprinter(pIntNew):0x12ff30
localprinter(pLocalString1):0x12ff60
localprinter(pLocalString2):0x12ff54
localvariable(nLocal):0x12ff48
localprinter(pMalloc):0x12ff24
localconstvariable(nLocalConst):0x12ff3c
  从输出结果可以看出程序数据的分配情况。
  通过new分配的位于堆上,5个int共20个字节,由于在堆上位16字节对齐,所以占用了32个字节从(48~88),内存对齐可是加速CPU对数据的访问,但是同时也造成了空间浪费,C/C++中的class、union和struct,可以通过#pragma pack()或者配置编译器来实现按要求对齐或者取消对齐。
  程序的内存分配如下图:
  全局/静态数据区            栈            堆
  g_nGlobal             pIntNew-->int[0..4]
  nLocalStatic           pMalloc--->char
  …                 ….
  "LocalString1"?-------pLocalString1
  "LocalString2"?-------pLocalString2
  nLocalConst
  全局/静态数据区是在程序编译阶段都已经分配好的,在整个程序运行过程中始终存在,用来保存全局变量、静态变量、常量等。
  其中字符串常量存储区域的数据是不可以修改的
  例如
  char *pLocalString1 = "LocalString1";
  pLocalString1[1]= 'a';//试图修改不可修改的内存
  二 堆和栈
  虽然平常都是"堆栈堆栈"连着说的,但是他们的定义和作用是有区别的
  在C/C++中,一个函数的内部变量以及传递给函数的参数等都是存储在栈中的。当退出这些变量的作用域时,这些栈的内容会被弹出释放。而是用malloc或者new申请的内存位于堆中,不会随着变量作用域的结束而自动释放,从而产生内存泄露。
  例如实例中的
  int *pIntNew = new int[5];
  char *pMalloc = (char *)malloc(1);
  pIntNew和pMalloc两个变量本身是位于栈的,当main()结束退出时,会被自动释放,而他们指向的内存在堆上,是不会自动释放的,因此造成内存泄露,所以必须显示的调用free或者delete。
  这里产生一个问题:既然栈上的内存会自动释放不存在泄漏问题,而堆必须显示释放容易产生内存泄漏,为什么还要是用堆呢?
  这是因为很多应用需要动态的管理数据,例如链表,而当需要新增节点插入链表时,此时就需要在堆上申请内存并插入节点。而且栈的大小也是有限制的,占用内存较多的对象只能在堆上分配。
  除了以上的差别外,他们在大小和效率方面需要注意:
  1、 大小
  通常一个程序可以使用的栈的大小是固定的,由编译器决定。例如vc2008栈的默认大小就是1MB,当然可以修改它的大小,但是通常都不会很大。
  int buf[1024*1024];//运行时会出错,栈溢出
  但是堆的大小要比栈大很多,它主要受限与系统的虚拟内存的大小,可以分配比较大的数据。
  2、效率
  栈上的内存是系统自动分配的,pop与push都用相应的指令操作,因此效率比较高,而且分配的都是练习的内存空间,不会产生碎片。而堆上的内存是程序动态申请和释放的,系统需要通过一定的算法在堆空间中寻找合适的空间再进行分配,并修改相应的维护堆空间的链表,再返回地址给程序,因此效率比栈低,而且容易产生碎片。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号