一个由C/C++编译的程序占用的内存分为以下几个部分:

1、栈区(stack)—  由编译器自动分配释放,存放函数的参数值局部变量的值等。其操作方式类似于数据结构中的栈。  
 2、堆区(heap) —  一般由程序员分配释放,若程序员不释放,程序结束时可能由OS(操作系统)回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。  
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。  
4、文字常量区  —常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区—存放函数体的二进制代码。

一般程序由new产生的动态数据放在堆区,函数内部的自动变量放在栈区.自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)都存放在全局数据区.因此它们并不会随着函数的退出而释放空间.

实例讲解:

int  a=0;   全局初始化区    
char *p1;   全局未初始化区    
int  main()    
{    
  int  b; //栈    
  char  s[]="abc"; //栈    
  char  *p2; //栈    
  char  *p3="123456"; //123456/0在常量区,p3在栈上。

static int c =0;//全局(静态)初始化区    
  p1 =  (char  *)malloc(10);  //分配得来得10和20字节的区域就在堆区
  p2  = (char  *)malloc(20);       
  strcpy(p3,"123456"); //123456/0放在常量区,编译器可能会将它与p3所指向的"123456"  优化成一个地方。    
}

下面详细讲解一下内存分配的几个区:

  • 栈:就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用。和堆一样,用户栈在程序执行期间可以动态地扩展和收缩。
  • 堆:当运行程序调用malloc()时就会从中分配,调用free()归还内存。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。堆可以动态地扩展和收缩。
  • 自由存储区:C++中通过new和delete动态分配和释放对象的抽象概念,通过new来申请的内存区域可称为自由存储区,通过delete归还内存。

基本上,所有的C++编译器默认使用堆来实现自由存储,运算符new和delete内部默认是使用malloc和free的方式来被实现,这时藉由new运算符分配的对象,说它在堆上也对,说它在自由存储区上也正确。

     说明:new和delete是运算符。

  • 全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的 C 语言中,全局变量又分为初始化的和未初始化的(初始化的全局变量和静态变量在一块区域,未初始化的全局变量与静态变量在相邻的另一块区域,同时未被初始化的对象存储区可以通过 void* 来访问和操纵,程序结束后由系统自行释放),在 C++ 里面没有这个区分了,他们共同占用同一块内存区。
  • 常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)

void f() { int* p=new int[5]; }

  这条短短的一句话就包含了堆与栈,看到 new,我们首先就应该想到,我们分配了一块堆内存,那么指针 p 呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针 p。在程序会先确定在堆中分配内存的大小,然后调用 operator new 分配内存,然后返回这块内存的首地址,放入栈中。

那么该怎么去释放呢?使用 delete []p。

堆与栈的讨论:

管理方式:
   堆中资源由程序员控制。
   栈资源由编译器自动管理,无需手工控制。

系统响应:
   对于堆,应知道系统有一个记录空闲内存地址的链表,当系统收到程序申请时,遍历该链表,寻找第一个空间大于申请空间的堆结点,删除空闲结点链表中的该结点,并将该结点空间分配给程序(大多数系统会在这块内存空间首地址记录本次分配的大小,这样delete才能正确释放本内存空间,另外系统会将多余的部分重新放入空闲链表中)。
   对于栈,只要栈的剩余空间大于所申请空间,系统为程序提供内存,否则报异常提示栈溢出。

空间大小:
   堆是不连续的内存区域(因为系统是用链表来存储空闲内存地址,自然不是连续的),堆大小受限于计算机系统中有效的虚拟内存(32bit系统理论上是4G),所以堆的空间比较灵活,比较大。
   栈是一块连续的内存区域,大小是操作系统预定好的,windows下栈大小是2M。

碎片问题:
   对于堆,频繁的new/delete??会造成大量碎片,使程序效率降低。
   对于栈,它是一个先进后出的队列,进出一一对应,不会产生碎片。

生长方向:
   堆向上,向高地址方向增长。
   栈向下,向低地址方向增长。

分配方式:
   堆都是动态分配(没有静态分配的堆)。
   栈有静态分配和动态分配,静态分配由编译器完成(如局部变量分配),动态分配由alloca函数分配,但栈的动态分配的资源由编译器进行释放,无需程序员实现。

分配效率:
   堆由C/C++函数库提供,机制很复杂。所以堆的效率比栈低很多。
   栈是极其系统提供的数据结构,计算机在底层对栈提供支持,分配专门寄存器存放栈地址,栈操作有专门指令

from:https://blog.csdn.net/duan19920101/article/details/50989431

C++内存分配方式-堆、栈、自由存储区、全局/静态存储区和常量存储区相关推荐

  1. C++程序内存分配方式(堆与栈)

    一.内存布局 1.栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量值等,其操作方法类似数据结构中的栈. 2.堆区(heap):一般由程序员分配释放,与数据结构中的堆毫无关系,分配方 ...

  2. C语言程序的内存分配方式

    1.内存分配方式  内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数 ...

  3. 内存分配方式及常见错误

    内存操作对于程序开发人员来说,永远是一块雷区.在这片区域,总是不断的埋雷.排雷,而且往往是排雷花了非常大的代价.记得在公司实习时,有大概2个星期的时间,team的几个人去排雷--有地方发生了memor ...

  4. 内存分配方式以及堆和栈的区别

    转载:https://blog.csdn.net/shanchangyi/article/details/51854795 对于一个程序要运行,涉及到的内存分配是一个首要问题,这里简单说一下一个简单的 ...

  5. java 常量 内存分配_Java内存分配之堆、栈和常量池

    寄存器:最快的存储区,位于不同于其他存储区的地方--处理器内部.寄存器的数量极其有限,所以寄存器由编译器根据需求 进行分配.你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象. 栈:存放基本类型 ...

  6. Java内存分配之堆、栈和常量池(转)

    摘录自http://www.cnblogs.com/SaraMoring/p/5687466.html Java内存分配主要包括以下几个区域: 1. 寄存器:我们在程序中无法控制 2. 栈:存放基本类 ...

  7. C/C++ 内存分配方式,堆区,栈区,new/delete/malloc/free

    内存分配方式有三种: [1] 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量, static 变量. [2] 在栈上创建.在执行函数时,函数内局 ...

  8. C/C++:程序的内存分配方式

    转载自:http://ryansky.blog.51cto.com/187974/86286 1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内 ...

  9. C/C++内存分配方式 .

    1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数时 ...

最新文章

  1. Git简介以及与SVN的区别
  2. IAR编译器的常见问题
  3. 【Linux入门到精通系列讲解】Centos 7软件安装的三种方式
  4. leetcode 611. Valid Triangle Number | 611. 有效三角形的个数(Java)
  5. Node.js从零开发Web Server博客项目笔记
  6. ora optimizer
  7. Tomcat version 5.5 only supports J2EE 1.2, 1.3, and 1.4 Web modules
  8. 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)...
  9. Java实现二维码的生成
  10. jenkins下载安装及环境搭建
  11. 厦门大学继续教育计算机科学毕业难吗,厦门大学工资待遇
  12. scrapy爬虫框架实现简单案例:爬取阳光平台内容
  13. 风扇空调照明灯动画的创建
  14. Bmob后端云实现无后端开发APP
  15. linux服务器503怎么解决,宝塔linux面板apache网站访问报错503 Service Unavailable怎么解决...
  16. 51nod 1597 有限背包计数问题 DP 根号分治
  17. EFCore之执行原生SQL语句
  18. 拉勾Java工程师P7训练营 高薪笔记
  19. HTML5 JS Canvas利用贝塞尔曲线绘制圆角矩形
  20. 【Unity3D 教程系列第 12 篇】如何用Unity写一个简易的计时器工具?

热门文章

  1. 展望10年内VR技术的盈利模式的发展历程
  2. 位置2的索引超出数组范围不能超过10_golang学习笔记--切片slice 与数组 arr
  3. 华三模拟器hcl实验手册_实验室 | # 实验室废气处理系统的设计#
  4. 动态网页开发技术(二):Servlet
  5. TypeScript完全解读(26课时)_14.ES6和Nodejs中的模块
  6. 关于移动端滚动穿透问题的解决
  7. 25条div+CSS编程提醒及小技巧整理
  8. 链接(跳转)router-link 和 路由实例Router
  9. UIViewAnimationOptions
  10. 软件测试方法的分类细谈