C语言内存分布图----栈空间、堆空间

 内存布局:栈,堆,BSS段(静态区),代码段,数据段

 什么是代码区、常量区、静态区(全局区)、堆区、栈区?

 C/C++堆区、栈区、常量区、静态数据区、代码区详解

 

-----------------------------------------------------------          4G(0xffff ffff)

内核空间              应用程序不许访问

------------------------------------------------------------         3G

 栈空间                 RW           局部变量保存位置            

--------------------------------------------------------------

文件映射区

-------------------------------------------------------------

运行时堆空间                           malloc

--------------------------------------------------------------

全局的数据空间            RW     (初始化为非0的(data)、未初始或初始化为0的(bss))     data段    bss段

只读数据段rodate         R         “ Hello world ”,                                            rodata段

代码段(只读)                 R                code                                                       text段

---------------------------------------------------------------0x00

代码段、rodata段:代码段对应程序中的代码(函数),rodata段常用于存储常量数据

data段:存放被初始化为非0的全局变量、static修饰的局部变量
bss段:存放未被初始化或初始化为0的全局变量、static修饰的局部变量

文件映射区:进程打开文件后,将文件内容从硬盘读到进程的文件映射区,以后就直接在内存中操作这个文件,读写完成后保存时,再将内存中的文件写入硬盘中。

栈:局部变量分配在栈中。函数调用传参过程也会用到栈

内核空间:将操作系统内核程序映射到这个区域。对于linux中的每个进程来说,它都认为这个系统只有它自己和内核空间。

ubuntu@ubuntu-virtual-machine:~$ size struct
   text       data        bss        dec        hex    filename
   1267        560          8       1835        72b    struct

一个局部变量前进行static修饰时,作用范围没有变还是当前函数内部,但是函数返回时,并没有释放,这一变量将进入静态数据段中的全局数据空间。

栈地址:运行时,函数内部使用的变量,函数一旦返回,就释放,生存周期仅限于函数内部

堆空间:运行时,可以自由、自我管理的分配和释放空间,生存周期由程序员决定

           分配:

                       malloc(),一旦成功,返回分配好的地址给我们,只需要接受,对于这个新地址的读法,由程序员灵活把握,输入参数决定分配的大小,单位是Byte。                       

  char *p;
   p = (char *)malloc(100);
   if(p ==NULL){
          error;
    }
  int a[5];

                释放:

 free(p);       

  存储类相关的关键字

auto:用来修饰局部变量(默认不写),分配在栈上(不初始化则值随机)。

static:用来修饰局部/全局变量,形成静态局部/全局变量。存储在全局数据空间

   static修饰函数:作用范围仅限于它的源文件,即只有本文件内才可以调用,函数名在其他文件内不可见。(限定作用域)

   static修饰局部变量:局限于特定函数,但出作用域并不释放,在函数体内静态变量的值也能维持。(限定生命周期)

   static修饰全局变量:作用范围局限于它的源文件,即只有本文件内的代码才可以访问它,变量名在其他文件内不可见。(限定作用域)

register:使用这一关键字修饰变量。编译器会尽量将其分配在及寄存器中,变为寄存器变量,提高访问效率。

extern:使用extern修饰全局变量,可以跨文件访问变量。比如a.c中用extern声明了一个全局变量,则在其他文件中便可直接使用该变量

volatile:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去优化这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
下面是volatile变量的几个例子:
1) 硬件会改变的变量(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量

三种链接属性:

内连接:static修饰的函数、全局变量
外链接:extern修饰的函数、局部变量
无连接:局部变量都是

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值