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, ...
随机推荐
- loj6851
(CF1761D Tester Solution in Chinese) 定义 \(L(v)=\log_2\operatorname{lowbit}(v+1)\):也就是说,\(L(v)\) 是 \( ...
- Kubernetes之Pod详解
1.Pod生命周期 pod创建 1. API Server 在接收到创建pod的请求之后,会根据用户提交的参数值来创建一个运行时的pod对象. 2. 根据 API Server 请求的上下文的元数据来 ...
- 2022-3-11内部群每日三题-清辉PMP
1.供应商通知项目经理可能延迟交付一个模块.项目经理应该怎么做? A.立即通知相关方. B.通过增加额外的天数来修改项目管理计划,并记录它们对项目时间的影响. C.审查风险管理计划以评估风险,然后通知 ...
- centos/redhat 多路径存储使用 - 客户端
DM Multipath(DMMP)工具 磁盘扫描 添加磁盘到dg--首先通知存储管理员划分相应的盘到指定的机器,说明共享--扫描磁盘(两个节点执行)[root@testrac1 ~]# echo & ...
- 「SOL」E-Lite (Ural Championship 2013)
为什么这数据能水到可以枚举角度 ac 啊 # 题面 给你 \(n\) 个平面向量 \((x_i,y_i)\),对于每个 \(k=1\sim n\),求「从给出的 \(n\) 个向量中不重复地选择 \( ...
- Flutter之EdgeInsets
EdgeInsets我们看看EdgeInsets提供的便捷方法: fromLTRB(double left, double top, double right, doublebottom):分别指定四 ...
- 网页制作02--banner制作
样本: 第一步:先做一个超大的通栏banner盒子. 第二步:在通栏盒子里面做一个版心的盒子 第三部:版心盒子里面在分左边盒子和右边盒子 1号盒子是通栏的大盒子banner,不给宽度,给高度.给一个蓝 ...
- 作业一:PCA降维练习
作业一:PCA降维作业 代码 点击查看代码 #author:qiao_px #@Time 2022/10/31 16:11 #@File ceshiPCA.py import pandas as pd ...
- 关于Centos7防火墙、端口、进程、开机自启、服务启动的常用命令
一.防火墙相关命令 1.查看防火墙状态 : systemctl status firewalld.service 注:active是绿的running表示防火墙开启 2.关闭防火墙 :systemct ...
- python机器学习——SVM支持向量机
背景与原理: 支持向量机是一种用来解决分类问题的算法,其原理大致可理解为:对于所有$n$维的数据点,我们希望能够找到一个$n$维的直线(平面,超平面),使得在这个超平面一侧的点属于同一类,另一侧的点属 ...