Linux下C程序的存储空间布局***
一个程序本质上都是由 BSS 段、data段、text段三个组成的。可以看到一个可执行程序在存储(没有调入内存)时分为代码段、数据区和未初始化数据区三部分。
- BSS段(未初始化数据区):在采用段式内存管理的架构中,BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。
- 数据段:在采用段式内存管理的架构中,数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
- 代码段:在采用段式内存管理的架构中,代码段(text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
程序编译后生成的目标文件至少含有这三个段,这三个段的大致结构图如下所示:
text段和data段在编译时已经分配了空间,而BSS段并不占用可执行文件的大小,它是由链接器来获取内存的。
bss段(未进行初始化的数据)的内容并不存放在磁盘上的程序文件中。其原因是内核在程序开始运行前将它们设置为0。需要存放在程序文件中的只有正文段和初始化数据段。
data段(已经初始化的数据)则为数据分配空间,数据保存到目标文件中。
数据段包含经过初始化的全局变量以及它们的值。BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段的后面。当这个内存进入程序的地址空间后全部清零。包含数据段和BSS段的整个区段此时通常称为数据区。
可执行程序在运行时又多出两个区域:栈区和堆区。
(4)栈区:由编译器自动释放,存放函数的参数值、局部变量等。每当一个函数被调用时,该函数的返回类型和一些调用的信息被存放到栈中。然后这个被调用的 函数再为他的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈就会被使用。栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容 量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出,用户能从栈中获取的空间较小。
(5)堆区:用于动态分配内存,位于BSS和栈中间的地址区域。由程序员申请分配和释放。堆是从低地址位向高地址位增长,采用链式存储结构。频繁的 malloc/free造成内存空间的不连续,产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。
下图将体现c的源文件对应存储空间:
此时程序还没有被放入内存,只是在硬盘存储的情况,此时bss并未占用空间。bss在链接的时候被获得内存空间。
下图表示程序运行,即程序在内存时的存储布局:
//main.c int a = 0; //全局初始化区 char *p1; //全局未初始化区 main() { static int c =0; //全局(静态)初始化区 int b; //栈 char s[] = "abc"; //栈 char *p2; //栈 char *p3 = "123456"; //"123456\0"在常量区,p3在栈上。 p1 = (char *)malloc(10); p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。 }
相关文章
- Linux IO - 同步,异步,阻塞,非阻塞
- Linux终端程序用c语言实现改变输出的字的颜色
- 网页瞬间转换成桌面应用级程序(IOS/Win/Linux)
- linux备份还原系统程序
- 跟老男孩学Linux运维:Shell编程实战2.1 什么是Shell
- Linux环境下安装dubbo-admin
- 如何拯救一台GRUB 2启动失败的Linux电脑
- OpenEuler 开启SSH的X11 Forwarding 支持,远程运行带有图形界面的程序(以Edge浏览器为例)而不需要被连接的Linux主机安装桌面环境
- 【Linux运维】centOS7 中安装可视化图形界面
- 使用jvisualVM监控远程linux服务器上运行的jar程序
- linux下如何退出tmux和重新进入tmux
- Linux下几款C++程序中的内存泄露检查工具
- 自助Linux之问题诊断工具strace
- linux NFS 客户端的安装
- 【转载】 Linux Hang Task 简介
- Linux系统小技巧(1):/dev/random设备可能导致java程序启动慢或者操作耗时不正常
- Linux修改时间的方法
- 【嵌入式Linux驱动开发】学习笔记(汇总版)
- 【正点原子MP157连载】第四十四章Linux SPI总线框架-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
- Windows和linux通过命令互传文件
- linux 日志统计
- Linux QQ
- Linux - 使用Ubuntu调试ARM Linux程序的简单准备
- Linux 后台进程管理和就几个“Ctrl+”命令 【转载】