c++程序内存布局以及堆栈概念详解

前言:

下图是c/c++的进程的内存分布布局图,搞清楚内存布局对于理解一个程序是非常重要的。


  一个程序运行起来,操作系统会给每个进程分配一个 4G 的程序地址空间,当然这都是虚拟地址空间,因为如果一个进程分 4G 的内存,那么就算有再多的内存也不够分。


   这些虚拟地址空间中的内存分段都是什么意思呢?下面进行讲解(linux系统为1G和3Gwindows系统为2G和2G):

在这里插入图片描述

一、首先进程地址空间的 1G(windows系统为2G) 内核空间是给操作系统使用的,我们用户是没有操作权限的。


二、剩下的 3G(windows系统为2G) 内存空间中,分为了栈区、内存映射段、堆区、数据段、bss段、代码段


1、栈区

(1)这里的栈和数据结构的栈并不相同,数据结构的栈是一种后进先出的数据结构,而内存划分的栈是操作系统按照栈的特性,给用户划分出的内存区间。


(2)栈区一般存放:函数体的局部变量、函数调用期间的所有参数压栈、函数的返回值注意栈区这段内存是由操作系统自己维护的,所以函数结束,在栈上的空间会由操作系统自己回收。

(3)32位应用程序(使用32位编译器编译),栈的默认内存大小一般为1M或者2M,64位应用程序(使用64位编译器编译)栈内存一般为4M,windows系统可以在GCC编译器编译前指定gcc 参数,修改默认栈大小

gcc -Wl,--stack=size

具体修改不同平台的栈内存,请拜读朕的另外一篇博客

https://blog.csdn.net/xujianjun229/article/details/120237390

(4)windows32位系统,一个进程所能使用的最大虚拟内存为2G,而一个线程的默认线程栈StackSize为1024K(1M),这样当线程数量逼近2000时,2000*1024K=2G(大约),内存资源就相当于耗尽。

2、堆区

(1)用户所操作的内存就是堆上的空间

(2)用户可以使用 malloc / calloc / realloc / new 申请堆上的空间,但是用户申请堆上的空间必须自己手动释放(free或者delete),不然会造成内存泄漏。

3、内存映射段

(1)存放 动态库 / 静态库,以及文件映射,匿名映射等等一切有依赖性的东西都在这段区域


4、数据段

(1)存放全局变量、静态类型的变量。

(2)当代码编译完后,在可执行程序这个文件中(二进制文件)已经把这些数据的空间划分好了,这种类型的数据,在程序运行以前,操作系统就将数据段中的数据加载到内存了。也就是说在进入 main 函数之前这些数据已经划分好空间了。

5、bss段

(1)其实在 C 语言中,数据段中还有一个 bss 段,这里面存放的是未初始化的全局变量和静态数据,而数据段中存放的是已经初始化过的全局变量和静态数据。

(2)数据段中的所有数据已经划分好空间了,但是 bss 段并没有给其中的数据划分空间。

6、代码段

(1)存放可执行代码,以及只读常量(字符串常量等等)。这段内存是只读的。
 

三、总结:一个程序本质上都是由栈区、内存映射段、堆区、数据段、bss段、代码段组成的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值