1.1 data 段

用来存储已经初始化的全局变量,也属于静态内存分配区,会占用程序文件空间。

与bss相比,data就容易明白多了,它的名字就暗示着里面存放着数据。当然,如果数据全是零,为了优化考虑,编译器把它当作bss处理。通俗的说,data指那些初始化过(非零)的非const的全局变量。它有什么特点呢,我们还是来看看一个小程序的表现。
int data_array[1024 * 1024] = {1};

int main(int argc, char* argv[])
{
    return 0;
}

[root@localhost data]# gcc -g data.c -o data.exe
[root@localhost data]# ll
total 4112
-rw-r--r-- 1 root root      85 Jun 22 14:35 data.c
-rwxr-xr-x 1 root root 4200025 Jun 22 14:35 data.exe

仅仅是把初始化的值改为非零了,文件就变为4M多。由此可见,data类型的全局变量是即占文件空间,又占用运行时内存空间的。

1.2 bss 段

BSS(Block Started by Symbol)用来存储未初始化的全局变量和静态变量,全局变量或静态变量值为0或NULL(对于指针变量而言)的通常会被编译器认为未初始化,属于静态内存分配区,不会占用程序文件空间,不存储这些变量在外存上,但是还是会占用一部分空间,这些空间用来标识未初始化的变量大小、属性等信息.

BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。

并不给该段的数据分配空间,只是记录数据所需要的空间大小。

它有什么特点呢,让我们来看看一个小程序的表现。
int bss_array[1024 * 1024] = {0};

int main(int argc, char* argv[])
{
    return 0;
}
[root@localhost bss]# gcc -g bss.c -o bss.exe
[root@localhost bss]# ll
total 12
-rw-r--r-- 1 root root   84 Jun 22 14:32 bss.c
-rwxr-xr-x 1 root root 5683 Jun 22 14:32 bss.exe

变量bss_array的大小为4M,而可执行文件的大小只有5K。 由此可见,bss类型的全局变量只占运行时的内存空间,而不占文件空间。

另外,大多数操作系统,在加载程序时,会把所有的bss全局变量全部清零,无需要你手工去清零。但为保证程序的可移植性,手工把这些变量初始化为0也是一个好习惯。

1.3 rodata

rodata的意义同样明显,ro代表read only,即只读数据(const)。

关于rodata类型的数据,要注意以下几点:

  • 常量不一定就放在rodata里,有的立即数直接编码在指令里,存放在代码段(.text)中。
  • 对于字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件(EXE/SO)中只存在一份拷贝。
  • rodata是在多个进程间是共享的,这可以提高空间利用率。
  • 在有的嵌入式系统中,rodata放在ROM(如norflash)里,运行时直接读取ROM内存,无需要加载到RAM内存中。
  • 在嵌入式linux系统中,通过一种叫作XIP(就地执行)的技术,也可以直接读取,而无需要加载到RAM内存中。

由此可见,把在运行过程中不会改变的数据设为rodata类型的,是有很多好处的:在多个进程间共享,可以大大提高空间利用率,甚至不占用RAM空间。同时由于rodata在只读的内存页面(page)中,是受保护的,任何试图对它的修改都会被及时发现,这可以帮助提高程序的稳定性。

text段:

代码段(codesegment/textsegment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

heap堆:

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

stack栈:

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

常量段:

常量段一般包含编译器产生的数据(与只读段包含用户定义的只读数据不同)。比如说由一个语句a=2+3编译器把2+3编译期就算出5,存成常量5在常量段中

1.8.变量与关键字

static关键字

用途太多,以致于让新手模糊。不过,总结起来就有两种作用,改变生命期限制作用域。如:
l         修饰inline函数:限制作用域
l         修饰普通函数:限制作用域
l         修饰局部变量:改变生命期
l         修饰全局变量:限制作用域

静态局部变量属于静态储存类别,在静态储存区内分配储存单元。在整个程序运行期间都不释放

const 关键字

倒是比较明了,用const修饰的变量放在rodata里,字符串默认就是常量。对const,注意以下几点就行了。
l         指针常量:指向的数据是常量。如 const char* p = “abc”; p指向的内容是常量 ,但p本身不是常量,你可以让p再指向”123”。
l         常量指针:指针本身是常量。如:char* const p = “abc”; p本身就是常量,你不能让p再指向”123”。
l         指针常量 + 常量指针:指针和指针指向的数据都是常量。const char* const p =”abc”; 两者都是常量,不能再修改。

violatile关键字

通常用来修饰多线程共享的全局变量和IO内存。告诉编译器,不要把此类变量优化到寄存器中,每次都要老老实实的从内存中读取,因为它们随时都可能变化。这个关键字可能比较生僻,但千万不要忘了它,否则一个错误让你调试好几天也得不到一点线索。

问题1,二进制文件不包含BSS段,那把BSS段放在哪 
答:修改有1000个全局变量,难道要BIN里要存1000个0吗?在链接脚本里把BSS段组织在一起,记下它的起始地址、结束地址,重定位后把这块内存清0即可

问题2:全局变量不初始化的话默认初始化为零,干嘛还要手动清零 
答:因为它是在BSS段的

C.2#【数据段】—2.数据段data、bss、rodata相关推荐

  1. 单片机内存分配之 .data .bss .rodata段

    一.概念 .bss段 存放没有初始化或者初始化为0的全局变量或者静态局部变量. .data段 存放初始化为非0,且非const属性的全局变量或者静态局部变量. .rodata段 存放字符串和const ...

  2. 代码段、数据段、bss段

    编译器在编译程序的时候,将程序中的所有的元素分成了一些组成部分,各部分构成一个段,所以说段是可执行程序的组成部分. 代码段:代码段就是程序中的可执行部分,直观理解代码段就是函数堆积组成的. 数据段(也 ...

  3. 内存空间分几部分:代码段、数据段,栈,堆 (收集整理)

    1.函数代码存放在代码段.声明的类如果从未使用,则在编译时,会优化掉,其成员函数不占代码段空间. 全局变量或静态变量,放在数据段, 局部变量放在栈中, 用new产生的对象放在堆中, 内存分为4段,栈区 ...

  4. BSS段,数据段,代码段,堆内存和栈

    BSS段,数据段,代码段,堆内存和栈 作者:delnabla 日期:2010-10-26 字体大小: 小 中 大 BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的 ...

  5. 数据段、代码段、堆栈段、BSS段的区别

    内存分配区域  32位操作系统下为:1G内核态,3G用户态 BSS段 :通常是指用来存放程序中 未初始化的全局变量.静态变量(全局变量未初始化时默认为0)的一块内存区域 数据段 :通常是指用来存放程序 ...

  6. C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

    BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 :数据 ...

  7. BSS段、数据段、代码段、堆与栈

    BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 ...

  8. Linux中的内存段(BSS、数据段、代码段、堆、栈)

    在Linux 系统中,在运行一个程序时,程序中未初始化的全局变量会被加载到以下哪个内存段中? BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量 ...

  9. 有关代码段、数据段、BOSS段、堆、栈的存储位置问题。。。

    在实模式存储管理方案下,系统的内存地址空间的布局一般可以分为五个段:代码段(text).数据段(data).boss段(boss).堆(heap).栈(stack). 下面以一段代码为实例: #inc ...

  10. 数据段、代码段、堆栈段、BSS段

    在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...

最新文章

  1. ssh,FTP到远程服务器时,显示自定义的警告信息
  2. VMware Vsphere4 资源分配与资源限制
  3. redis的spring的xml配置
  4. 26. linix脚本启动java程序
  5. 系统通知并发问题_iOS 14 系统又出现问题了,短信通知无响应
  6. SpringCloud2.0入门4-springboot-admin监控
  7. ITK:侵蚀二进制图像
  8. EFI BIOS下的磁盘管理工具Diskpart,Efifmt与Efichk(转)
  9. [转]使用 LDAP 组或角色限制访问,包含部分单点登录SSO说明
  10. 《流浪地球》 电影全集
  11. 水质php比较低,鱼缸水质的PH太高或太低怎么办?调节PH值一般用以下4件物品
  12. MATLAB中fspecial()函数的用法
  13. 【PS专题】PS钢笔压力有感叹号怎么消除
  14. 集合--List集合练习--集合的嵌套、Random类获取随机数
  15. win10有一个隐藏的超级管理员帐户,拥有全部权限,如何启用它
  16. Quality-Estimation2 (翻译质量评价-在BERT模型后面加上Bi-LSTM进行fine-tuning)
  17. 5 个免费练习黑客技术的网站!
  18. numpy按照某列排序
  19. 一般可行性研究报告的主要内容和要求
  20. 编程小白的人工智能路之Gabor滤波提取掌纹特征并对比掌纹相似度(一)

热门文章

  1. 【C语言基础】C语言实现扫雷
  2. 前端学习之Bootstrap入门 网格系统
  3. 当前的安全设置不允许从该位置下载文件 解决方法
  4. mysql 批量插入亿级数据做测试用
  5. java 获得两个时间段差距:时分秒,两个时间相差距离多少天多少小时多少分多少秒
  6. leetcode 322: 零钱兑换
  7. 土壤容重壤理化性质的重要指标之一
  8. VTK 学习----VTK基础-VTK概述和架构概述
  9. FlinkSQL读取Hbase数据
  10. windows系统-串口设备导致鼠标乱跳的问题