Linux把数据存在程序区,linux 下C程序在运行时的内存分布情况

一、内核空间和用户空间

对于32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的权限。为了保证用户进程不能直接操作内核,保证内核安全,操作系统将虚拟空间划分为两部分,一部分是内核空间,一部分是用户空间。针对Linux操作系统,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF)供内核使用,称为内核空间(window os占用2G),而其他的(3G)字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。每个进程都可以通过系统调用进入到内核。其中在Linux系统中,进程的用户空间是独立的,而内核空间是共有的(每个进程都认为自己有4G的空间),进程切换时,用户空间切换,内核空间不变。

09dc32afa489f24fde2b2156d53ce01d.png

二、程序在运行时内存的分布情况

ff8099f178635c89818df9dd7d1d8194.png

(1)代码段(Text segement):

通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。

C语言中使用char *p = "linux";定义字符串时,字符串"linux"实际被分配在代码段。

这个地方还有一种说法:

".rodata"段存放的是只读数据,一般是程序里面的只读变量(如const修饰的变量)和字符串常量。

(个人理解:究竟是代码段还是只读数据段都不重要,只要知道只读即可)

(2)数据段(data segment):

存放程序中已显式初始化为非零的全局变量和static修饰的局部变量的一块内存区域。

(普通局部变量分配在栈上,静态局部变量分配在.data段)

(3)BSS段(Block Started by Symbol segment):(又叫ZI(zero initial)段)

未初始化或显式初始化为0的全局变量放在bss段。

执行程序在运行时又多出两个区域:栈区和堆区。

注意区分:数据段(.data)和bss段的区别和联系:二者本来没有本质区别,都是用来存放C程序中的全局变量的。区别在于把显示初始化为非零的全局变量存在.data段中,而把显式初始化为0或者并未显式初始化(C语言规定未显式初始化的全局变量值默认为0)的全局变量存在bss段。

(4)栈区:

运行时自动分配、自动回收:栈是自动管理的,不许程序员干预;

栈区是从高地址位向低地址(虚拟地址)位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出,用户能从栈中获取的空间较小。

栈内存由于反复使用,每次使用后程序不会去清理,因此分配到时保留原来的值。

(5)堆区:

由程序员申请分配和释放,需要写代码去申请malloc和释放free;

堆是从低地址位向高地址位增长(虚拟地址),采用链式存储结构。频繁的 malloc/free造成内存空间的不连续,产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。

REF:

标签:初始化,显式,程序,内核,linux,空间,全局变量,内存

来源: https://blog.csdn.net/wwwlyj123321/article/details/100107984

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值