全局内存BSS,DATA,RODATA的区别以及其他内存区间相关

刚接触c语言的时候,了解了全局变量这个概念,只知道所谓全局变量的意思就是代码文件里面所有的函数都可以随时调用修改的变量,而其实这种理解是十分不准确的,但随着后期学习的深入,接触了计算机组成原理和汇编的相关知识,通过阅读其他大神的博客,学到了很多,发现所谓全局变量其实是存放在全局内存中的变量,以及很重要的一点就是强调全局,这个所谓的全局指的是变量的生命周期,而不是他的作用域,先前的理解误区正是将全局理解为仅指作用域。

static:使用static声明的变量,他可能是在某一个函数中进行申明,这时可以说这个变量的作用范围是局部的,但是生命周期是全局的。

一般而言,定义在一起的两个全局变量在内存中位置是相邻的,这局简单的话有时很有用,比如一个全局变量受到了破坏,那么程序中定义位置前后数组或是其他元素可能出现了越界访问,代码排错的时候可以快速缩小错误位置区间。

BSS:

如果一个全局变量没有被初始化 或者被初始化为0,那么这个全局变量就被存放在bss内存中。

这种类型的全局变量的特点:
作如下变量声明:
int bssTest[1024*1024]={0};

编译链接结束后,查看可执行文件大小,远小于4M,这说明bss类的全局变量不占用文件存储空间而只占用程序运行内存空间

对于大多数的操作系统,在程序加载的时候会自动的将在所有bss全局变量清零,无需手动清零,但是手动清零是一种很好的编程习惯

DATA:

正如其名:数据。
data内存放那些初始化过的非const全局变量,当然如果初始化为0,编译器还是会被把他当作bss来处理。
对于其特点,与BSS对应来看,同样在代码中也做如下声明:
int dataTest[1024*1024]={1};

编译链接结束查看可执行文件大小发现大小为4M+,于是,data全局变量占用文件空间也占用运行内存空间

RODATA

:所谓RO,read only,只读,也就是只允许读取而不允许修改的意思。
对于RODATA类的数据:

  • 常量不一定就放在RODATA内, 有的立即数直接编码在指令里,存放在代码段中(text)
  • 字符串常量在经过编译器处理的时候会被自动去掉重复字符串,保证一格字符串在一个可执行文件中只有一份拷贝。
  • RODATA是 多线程共享内存 ,这样做的好处就是可以提高空间的利用率。
  • 有的嵌入式系统中,rodata放在ROM中(norflash),运行时直接加载ROM而无须加载到RAM中。
  • 嵌入式linux系统中有一种技术叫做 XIP(就地执行) ,同样能实现直接读取而无须加载到RAM中。

把运行过程中不会发生改变的数据放到rodata区是有很多好处的,多线程共享,提升空间利用率甚至不占用RAM空间,以及rodata的只读属性在某些情况下可以阻止意外的数据破坏,能够提升程序运行的稳定性


上面提到了static关键字,其实static关键字的作用就是改变生命周期限制作用域

  1. 修饰内联函数(inline func):限制作用域。
  2. 修饰普通函数:限制作用域。
  3. 修饰局部变量:改变生命周期。
  4. 修饰全局变量:先知作用域。

对于const关键字:

使用const的常量放在rodata里面,字符串默认是常量:有如下定义:

char *p = “hello world!”;
const char *p = “hello world!”;

这两种声明,无论是上者还是下者,当试图使用p指针去修改字符串内容的时候都会提示错误,字符串所在位置都是静态区,但是p指针本身所在位置有区别

这个就涉及了另外的问题:

  • 指针常量和常量指针的问题(修饰就近原则):

指针常量:指向的数据是常量,这里我做如下定义:
const char *p = {hello};//这种定义下const修饰char *p也就是p指针指向的内容,既p指向的字符串作为常量放在bss,而指针p并不是常量,我们还可以改变他的指向,让它指向别的字符串。

常量指针,顾名思义,指针是常量,定义方式如下:
char *const p = {hello};//p本事就是一个常量,只能指向hello\0这个字符串而不能改变。

内存的其他区域:

heap堆区:这个区域用来存储使用malloc分配的内存空间,使用完以后需要使用free手动释放来管理存储空间,虽然程序退出后OS也会自动释放。
stack栈区:这一部分的存储空间是编译器在编译代码的时候就分配好点的固定存储空间

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值