Linux下C语言程序的内存布局
在《虚拟地址空间以及编译模式》一节中讲到,虚拟地址空间在32位环境下的大小为 4GB,在64位环境下的大小为 256TB,那么,一个C语言程序的内存在整个地址空间中是如何分布的呢?数据在哪里?代码在哪里?为什么要这样分布?这些就是本节要讲解的内容。
程序内存在地址空间中的分布情况称为内存模型(Memory Model)。内存模型由操作系统构建,在Linux和Windows下有所差异,并且会受到编译模式的影响,本节我们讲解Linux下32位环境和64位环境的内存模型。
内核空间和用户空间
对于32位环境,理论上程序可以拥有 4GB 的虚拟地址空间,我们在C语言中使用到的变量、函数、字符串等都会对应内存中的一块区域。
但是,在这 4GB 的地址空间中,要拿出一部分给操作系统内核使用,应用程序无法直接访问这一段内存,这一部分内存地址被称为内核空间(Kernel Space)。
Windows 在默认情况下会将高地址的 2GB 空间分配给内核(也可以配置为1GB),而 Linux 默认情况下会将高地址的 1GB 空间分配给内核。也就是说,应用程序只能使用剩下的 2GB 或 3GB 的地址空间,称为用户空间(User Space)。
Linux下32位环境的用户空间内存分布情况
我们暂时不关心内核空间的内存分布情况,下图是Linux下32位环境的一种经典内存模型:

对各个内存分区的说明:
| 内存分区 | 说明 |
|---|---|
| 程序代码区 (code) |
存放函数体的二进制代码。一个C语言程序由多个函数构成,C语言程序的执行就是函数之间的相互调用。 |
| 常量区 (constant) |
存放一般的常量、字符串常量等。这块内存只有读取权限,没有写入权限,因此它们的值在程序运行期间不能改变。 |
| 全局数据区 (global data) |
存放全局变量、静态变量等。这块内存有读写权限,因此它们的值在程序运行期间可以任意改变。 |
| 堆区 (heap) |
一般由程序员分配和释放,若程序员不释放,程序运行结束时由操作系统回收。malloc()、calloc()、free() 等函数操作的就是这块内存,这也是本章要讲解的重点。 注意:这里所说的堆区与数据结构中的堆不是一个概念,堆区的分配方式倒是类似于链表。 |
| 动态链接库 | 用于在程序运行期间加载和卸载动态链接库。 |
| 栈区 (stack) |
存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈。 |
在这些内存分区中(暂时不讨论动态链接库),程序代码区用来保存指令,常量区、全局数据区、堆、栈都用来保存数据。对内存的研究,重点是对数据分区的研究。
程序代码区、常量区、全局数据区在程序加载到内存后就分配好了,并且在程序运行期间一直存在,不能销毁也不能增加(大小已被固定),只能等到程序运行结束后由操作系统收回,所以全局变量、字符串常量等在程序的任何地方都能访问,因为它们的内存一直都在。
常量区和全局数据区有时也被合称为静态数据区,意思是这段内存专门用来保存数据,在程序运行期间一直存在。
函数被调用时,会将参数、局部变量、返回地址等与函数相关的信息压入栈中,函数执行结束后,这些信息都将被销毁。所以局部变量、参数只在当前函数中有效,不能传递到函数外部,因为它们的内存不在了。
常量区、全局数据区、栈上的内存由系统自动分配和释放,不能由程序员控制。程序员唯一能控制的内存区域就是堆(Heap):它是一块巨大的内存空间,常常占据整个虚拟空间的绝大部分,在这片空间中,程序可以申请一块内存,并自由地使用(放入任何数据)。堆内存在程序主动释放之前会一直存在,不随函数的结束而失效。在函数内部产生的数据只要放到堆中,就可以在函数外部使用。
Linux下C语言程序的内存布局的更多相关文章
- linux下C/C++程序的内存布局
内核空间和用户空间: 我们在编写程序时使用的内存空间叫虚拟内存,程序在运行时,要完成虚拟内存到物理内存的转换.假如在32位环境上,理论上我们可以使用的虚拟内存空间是4GB,但实际上这4GB并不能完全给 ...
- C语言程序的内存布局
C语言程序的内存布局 一:C语言程序的存储区域 C语言编写的程序经过编绎-链接后,将形成一个统一的文件,它由几个部分组成,在程序运行时又会产生几个其他部分,各个部分代表了不同的存储区域: 1.代码段( ...
- linux下C语言实现的内存池【转】
转自:http://blog.chinaunix.net/uid-28458801-id-4254501.html 操作系统:ubuntu10.04 前言: 在通信过程中,无法知道将会接收到的 ...
- Anatomy of a Program in Memory.剖析程序的内存布局
原文标题:Anatomy of a Program in Memory 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的精彩文章翻译 ...
- linux 下C语言学习路线
UNIX/Linux下C语言的学习路线.一.工具篇“公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工 ...
- Unix和Linux下C语言学习指南
转自:http://www.linuxdiyf.com/viewarticle.php?id=174074 Unix和Linux下C语言学习指南 引言 尽管 C 语言问世已近 30 年,但它的魅力仍未 ...
- 笔记整理——Linux下C语言正则表达式
Linux下C语言正则表达式使用详解 - Google Chrome (2013/5/2 16:40:37) Linux下C语言正则表达式使用详解 2012年6月6日Neal627 views发表评论 ...
- linux下C语言多线程编程实例
用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...
- Linux下C语言编程基础学习记录
VIM的基本使用 LINUX下C语言编程 用gcc命令编译运行C语言文件 预处理阶段:将*.c文件转化为*.i预处理过的C程序. 编译阶段:将*.i文件编译为汇编代码*.s文件. 汇编阶段:将*.s ...
- Linux下的 sniff-andthen-spoof程序编写
Linux下的 sniff-andthen-spoof程序编写 一.任务描述 在本任务中,您将结合嗅探和欺骗技术来实现以下嗅探然后欺骗程序.你需要两台机器在同一个局域网.从机器A ping IP_X, ...
随机推荐
- darkriscv笔记
1 按照默认设置,前4K空间为ROM,后4K空间是RAM.为什么RAM需要初值,初值从哪儿来? 2 指令分类 LUI: AUTPC: JAL: JALR: BCC : BEQ/BGE /BGEU/BL ...
- 肖sir__面试笔试题__阿里笔试题
第一题: #给定一个无序数组nums和一个目标值target,返回数组中两个元素的和为target的算法,时间复杂度为O(1);def func1(nums,target): dict1 = { ...
- React 事件绑定this指向
1. 推荐:使用class的实例方法 class Hello extends React.Component { handleClick = () => { this.setState({ .. ...
- 2022-04-19内部群每日三题-清辉PMP
1.一个项目的完工预算(BAC)为100,000美元.目前的项目报告显示该项目符合进度和预算.一位团队成员对相关工作包进行自下而上估算,表明剩余工作将比原计划少用10,000美元,并且仍能按进度计划交 ...
- Jenkins+Appium+Pytest+Allure集成
前提: 已经部署好了Jenkins环境,包括工具配置等 我的环境: Jenkins服务由安装在虚拟机上的Docker启动 Appium相关运行环境安装在虚拟机所在的主机上windows 方式:在Jen ...
- jmeter非GUI模式压测并生成测试报告
关于jmeter非GUI模式压测并生成测试报告 1.脚本调通后,在DOS命令栏进入脚本存在的位置 如果不想通过DOS进入脚本路径,则可以直接指定执行路径,命令如下: JMeter默认去当前目录寻找脚本 ...
- pg数组类型
数据库版本 postgres=# SELECT version(); version---------------------------------------------------------- ...
- Linux常用指令1
1.文件和目录的相关指令: ·cd:打开 ·pwd:查看当前所在的目录 ·mkdir:新建目录 ·rmdir:删除目录 ·ls:文件和目录查看 ·cp:复制 ·rm:删除 ·mv:移动 2.文本文件内 ...
- ZSTUOJ刷题⑨:Problem H.--尖兵
Problem H: 尖兵 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 4691 Solved: 2112 Description 星光人已经出发了 ...
- vue后台管理系统——权限管理模块
电商后台管理系统的功能--权限管理模块 1. 权限管理业务分析 通过权限管理模块控制不同的用户可以进行哪些操作,具体可以通过角色的方式进行控制,即每个用户分配一个特定的角色,角色包括不同的功能权限. ...