你写的C语言代码在内存里是如何布局的?

C语言的代码内存布局详解 一个程序本质上都是由 BSS 段、data段、text段三个组成的。这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。 BSS段:在采用段式内存管理的架构中,BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Starte 阅读详情
一个程序本质上都是由 BSS 段、data段、text段三个组成的。这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。


  • BSS段:在采用段式内存管理的架构中,BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。
  • BSS 代表 “block storage segment” (原来是以一个符号开头的块),BSS 部分中保留的内存在程序启动时初始化为零。

  • 数据段:在采用段式内存管理的架构中,数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

  • 代码段:在采用段式内存管理的架构中,代码段(text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

程序编译后生成的目标文件至少含有这三个段,这三个段的大致结构图如下所示:

其中.text即为代码段,为只读。.bss段包含程序中未初始化的全局变量和static变量。data段包含三个部分:heap(堆)、stack(栈)和静态数据区。


  • 堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

  • 栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

当程序在执行时动态分配空间(C中的malloc函数),所分配的空间就属于heap。其概念与数据结构中“堆”的概念不同。


stack段存放函数内部的变量、参数和返回地址,其在函数被调用时自动分配,访问方式就是标准栈中的LIFO方式。(因为函数的局部变量存放在此,因此其访问方式应该是栈指针加偏移的方式,否则若通过push、pop操作来访问相当麻烦)


data段中的静态数据区存放的是程序中已初始化的全局变量、静态变量和常量。


在采用段式内存管理的架构中(比如intel的80x86系统),BSS 段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时 BSS 段部分将会清零。BSS 段属于静态内存分配,即程序一开始就将其清零了。


比如,在C语言之类的程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的全局变量保存在.bss 段中。


在《Programming ground up》里对.bss的解释为:

There is another section called the .bss. This section is like the data section, except that it doesn’t take up space in the executable.


text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;而BSS段不在可执行文件中,由系统初始化。

图引自《C专家编程》

BSS段只保存没有值的变量,所以事实上它并不需要保存这些变量的映像。运行时所需要的BSS段大小记录在目标文件中,但BSS段并不占据目标文件的任何空间。

举个具体的C语言的例子吧:

//main.c

int a = 0; //全局初始化区
char *p1; //全局未初始化区

int main(void)
{
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字节的区域就在堆区。

return 0;
}
C++11 新特性 1、指针、智能指针(nullptr、shared_ptr、std::weak_ptr) (1)nullptr 作用: C++11 引入了 nullptr 关键字,专门用来区分空指针、0 原有问题:传统 C++ 会把 NULL、0 视为同一种东西,这取决于编译器如何定义 NULL 实现:nullptr 的类型为 nullptr_t,能够隐式的转换为任何指针或成员指针的类型,也能和他们进行相等或者不等的比较。当需要使用 NULL 时候,养成直接使用 nullptr的习惯 NULL的定义 #ifdef __c 阅读详情

相关推荐

C 语言中进程的内存布局

学习C语言中进程的内存布局

m0_68865445的博客 695

C语言内存四区的学习总结(一)---- 静态区

最近重新学习C语言相关知识,重新提到内存四区的概念,那么在之前的学习的基础上,在这儿做一个简单的总结与分享。 一、内存四区建立的流程 可以简单直观的查看下面的这个图片,直接的说明我们的程序在内存中是如何去存储,运行。。。。 ​ 程序运行的流程说明 1、操作系统把物理硬盘代码 load到内存 2、操作系统把c代码分成四个区 3、操作系统找到 main函数入口执行 二、各区元...

a2196779的博客 1071

揭秘C语言内存布局:从代码到运行,深入理解四大分区

本文深入解析了C语言程序在内存中的四大分区布局。通过预处理、编译、汇编和链接四个步骤,程序最终生成的可执行文件已包含代码区和数据区两大静态分区。代码区存放只读的机器指令,数据区则分为已初始化(.data)、未初始化(.bss)和只读数据(.rodata)三个子区域。程序运行时还会动态生成栈区和堆区:栈区由编译器自动管理,存放局部变量和函数参数;堆区则需程序员手动分配释放。文章通过代码示例验证了各区域特性,并使用size命令直观展示了各段大小。最后以内存地址分布图总结了四大分区在虚拟内存中的相对位置关系,帮助

Web安全工具库 1601

拿下鹅厂一面!

哈希表的时间复杂度为O(1)是因为它使用了一种叫做哈希函数的方法来直接计算出数据应该存储在哪个位置,而不需要逐个检查每个位置。这就像是你有一个巨大的文件柜,每个抽屉都有一个唯一的编号,你可以直接通过编号找到你需要的文件,而不需要从第一个抽屉开始逐个查找。当你插入、删除或查找一个元素时,哈希表首先使用哈希函数计算出元素的哈希值,然后使用这个哈希值作为索引直接访问到数组中的相应位置。因此,这些操作的时间复杂度都是O(1)。

IT界那些事儿 215

C语言 内存布局学习总结

前言 C语言内存布局 参考链接 前言   C语言的内存布局对于理解C语言类型的作用域和声明周期,以及C语言对操作系统资源的使用规则至关重要,因此,理解C语言的内存布局模型,有助于深入理解C语言编程思想,以及高屋建瓴的学习C++内存布局模型。   本文是对C语言内存布局的学习总结。 C语言内存布局   一个程序本质上都是由BSS段、data段和text段三部分组成...

大山喵写博客的地方 1106

怎样在 C 语言中进行结构体的内存布局控制?

大端(Big-Endian):高位字节存储在低地址,低位字节存储在高地址。小端(Little-Endian):低位字节存储在低地址,高位字节存储在高地址。以下是一个示例来说明大端和小端的存储方式:假设一个 4 字节的整数0x12345678要存储在内存中。(地址从低到高)(地址从低到高)在 C 语言中,结构体的内存布局控制是一个重要但有时容易被忽视的方面。

技术笔记 697

C语言内存布局

本文详细解析了C语言程序的内存布局结构,涵盖代码段(TEXT)、只读数据段(RODATA)、数据段(DATA)、BSS段、堆和栈的存储特性与区别。重点澄清了const变量的存储位置(全局const在RODATA段,局部const在栈上),并通过代码示例验证了各内存区域的地址分布。文章还对比了字符串常量与字符数组的内存差异,以及静态变量的存储位置,为理解C程序内存管理提供了清晰的参考框架。

道阻其长,未来可期。笔耕不辍,行则将至! 1911

Cadence SIP Layout 简单教程-第二章

[从whp1920 网易博客迁移至优快云] 第一章在正式布线之前做了必须做的准备工作,下面进入正题,打开Candence SIP RF Layout GXL软件。 第一节 导入外形尺寸 打开SIP设置文件保存路径,如下图所示进入导入DXF页面,选中前一章时画好的外框图。打开导入界面后,再进入DXF In Edit/View Layers界面选择所有层,导入Class选择DRAWING FOR...

whp1920的博客 6939

C语言之内存布局

C语言的内存布局规律,根据内存地址从低到高分别划分为: 代码段(Text segment):通常是指用来存放程序执行代码的一块内存区域。这部分区域大小在执行代码之前就已经确定了,并且内存区域通常属于只读,在代码段中,也可能包含一些只读的常数变量,例如字符串变量等。 数据段 (Initialized data segment):通常用来存放已经初始化的全局变量和局部静态变量; BSS段(Unin...

Backpace_的博客 717

图像质量评估(5) -- 畸变(Distortion)

当图像中原本应该是直线的地方看起来发生了不自然的变形或扭曲时,我们称为图像畸变。有三种类型的镜头畸变:桶形畸变(后文使用英文barrel),枕形畸变(后文使用pincushion)和胡子畸变(后文使用英文wavef或mustache,这种畸变里包含了桶形畸变和枕形畸变)。有一个重要的点需要注意,根据透镜的类型以及透镜是否能够从相机中移除等条件不同,畸变会有不同的表现。 总的来说,旋转对称光学系统功能上会产生和物体几何相似的图形。但也有少数特殊的系统是例外,例如鱼眼镜头,这种镜头几何是故意设计为

vivo01的专栏 2万+

全15万字丨PyTorch 深度学习实践、基础知识体系全集;忘记时,请时常回顾。

本篇博客介绍的知识是——深度学习之PyThon框架基础。这是深度学习/神经网络的基础,多次回顾,会有不一样的感受。书读百遍,其义自见。

追光者♂:记录、分享、总结、提升,现象级专栏《Python从入门到人工智能》作者,无惧黑暗,坚信曙光 5785

C语言动态内存管理与内存空间布局

在C语言中,内存管理是一个至关重要的概念。动态内存管理允许程序员在程序运行时根据需要分配和释放内存,这为程序提供了灵活性和高效性。同时,了解内存空间布局有助于优化程序性能和避免内存相关问题。本文将从C语言的角度详细讲解动态内存管理以及内存空间布局。

My__Space的博客 689

MC_SetOverride指令详细应用介绍(基恩士PLC)

基恩士KV系列PLC和松下总线绝对值伺服运动控制(详细配置+轴控完整ST源代码)

RXXW_Dor的博客 334

0-C语言中有关内存布局的概念

程序代码区用来保存指令常量区、全局数据区、堆、栈都用来保存数据。程序代码区、常量区、全局数据区在程序加载到内存后就分配好了,并且在程序运行期间一直存在,不能销毁也不能增加(大小已被固定),只能等到程序运行结束后由操作系统收回,所以全局变量、字符串常量等在程序的任何地方都能访问,因为它们的内存一直都在。**函数被调用时,会将参数、局部变量、返回地址等与函数相关的信息压入栈中,函数执行结束后,这些信息都将被销毁。**所以局部变量、参数只在当前函数中有效,不能传递到函数外部,因为它们的内存不在了。

weixin_51753483的博客 1063

YOLO11-Seg优化:卷积变体系列篇 | 动态蛇形卷积(Dynamic Snake Convolution) | ICCV2023

动态蛇形卷积(Dynamic Snake Convolution),增强微小特征提取能力,引入到YOLO11-Seg,与C3k2结合实现二次创新

会AI的学姐 368

【银河麒麟V10】【桌面】【服务器】系统启动问题

1、如果之前运行好好的,重启后系统报错,一般80%是因为fstab的问题,回想下之前有没有添加过外接存储,修改过/etc/fstab,如果是的话一般是因为存储异常(比如网络存储无法连接,本地存储路径变化)导致系统开机自检失败,导致无法正常启动; 处理方式:进入单用户(单用户进入的几种方式上面有专门文章介绍),修改/etc/fstab,将新增的内容暂时注释掉,然后重启系统,能正常进入系统后再分析失败原因。 ...

桂安俊@KylinOS 3万+

C语言的内存布局

答:因为变量 a 和变量 b 都是局部变量,它们的作用域仅限于所在的函数之中。当函数被调用时,在栈上为它们分配内存空间,当函数结束时,空间自动被回收。分析:根据代码上下文我们可以推断出 array 是一个指针数组,数组中的每个元素是一个函数指针,该函数的参数和返回值都是 void。答:在定义字符变量 a 和 b 的时候,两个局部变量的地址是连续的,各占一个字节,并且 b 在前 a 在后。如果这时候给它赋值,那么将 “污染” a 变量的地址空间,很不幸,我们确实这么做了。

weixin_63833170的博客 876

matlab 基于离散余弦变换DCT的最小二乘相位解缠

最小范数法是寻求在解包裹相位的局部微分与包裹相位微分相一致的条件下, 逼近于真实相位分布的解包裹相位分布。目标是使解包裹相位与包裹相位曲面的差最小

点云侠的博客 285

C语言程序的内存布局

C语言程序的内存布局 一:C语言程序的存储区域           C语言编写的程序经过编绎-链接后,将形成一个统一的文件,它由几个部分组成,在程序运行时又会产生几个其他部分,各个部分代表了不同的存储区域: 1.代码段(Code or Text): 代码段由程序中的机器码组成。在C语言中,程序语句进行编译后,形成机器代码。在执行程序的过程中,CPU的程序计数器指向代码段的每一条代码,并由处

philips的专栏 621

HLA分型

HLA分型 一、根据WES的tumor数据进行数据分型 选用hlahd 软件安装及使用 [root@18605fd8771e ~]# wget https://jaist.dl.sourceforge.net/project/bowtie-bio/bowtie2/2.4.1/bowtie2-2.4.1-linux-x86_64.zip [root@18605fd8771e ~]# unzip bowtie2-2.4.1-linux-x86_64.zip && mv bowtie2-2.4.1

qq_23435961的博客 2487

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C语言中编码内存,C语言的代码内存布局详解

原标题:C语言的代码内存布局详解 吴鉴鹰单片机开发板地址店铺:【吴鉴鹰的小铺】地址:【https://item.taobao.com/item.htm?_u=ukgdp5a7629&id=524088004171】一个程序本质上都是由 BSS 段、data段、text段三个组成的。这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统...

weixin_39816362的博客 158

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C语言结构体全解析:从入门到内存布局

C语言结构体全解析:从入门到内存布局。记得关注本博客,持续重磅内容更新,有需求可以私信沟通!

奋斗在路上的博客 1135

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C语言内存模型

Linux下32位环境的用户空间内存分布情况待更20230816。

Dontla的博客 1170
上一篇: 如何让你的Tomcat在开机时自动以服务的形式启动
下一篇: Java内存布局【图】以及java各种存储区【详解】
HNFXS985
博客等级 码龄14年 219粉丝 150原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值