虚拟内存的结构

C语言编译后文件的结构

c语言中总体来说,编译后的程序可以分为在硬盘和在内存中运行两大种情况;每种情况下所启用的结构不一样;

1. 硬盘上:text段 data段 其他段(调试的段,动态库共享库链接表的段)
2. 内存中:text段 data段 bbs段 heap stack

注意:位于硬盘上段其大小不可变(一般情况下)
在这里插入图片描述

如下是一个程序在运行时的4G虚拟内存的组成:
在这里插入图片描述

  1. 栈用于维护函数调用的上下文,离开了栈,函数的调用就办法实现了。栈通常在用户更高的地址空间处分配,通常有数兆字节的大小。栈主要用来存放局部变量,函数调用时会在栈上有一系列的保留现场(保存上下文)及传递参数的操作。自动变量和函数调用时所需保存的信息都存放在此段中。

  2. 堆用来容纳应用 程序动态分配的内存区域,当程序 使用malloc或new 的时候就是得到来自堆中的内存。堆统称在栈的下方(低地址方向,但是不是紧邻的)。堆一般比栈要更大一点,一般会达到几十甚至是数百兆字节。

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

  4. 数据段(data segment):读写权限;存已被初始化了的静态数据,包含明确的初始化值,保存在硬盘上,由.exec读取。数据段通常是指用来存放程序中 已初始化的全局变量或者静态变量 的一块内存区域。

  5. BSS 段(Block Started by Symbol )未初始化的数据段,不保存在硬盘上,只是记录数据所需空间的大小,程序开始执行之前,由内核进行初始化为0。

  6. 常量数据段(.rodata):ro表示read only,用于 存放不可变修改的常量数据 ,一旦程序中对其修改将会出现段错误
    (1) 程序中的常量不一定就放在rodata中,有的立即数和指令编码放在.text中
    (2)对于字符串常量,若程序中存在重复的字符串,编译器会保证只存在一个,一般声明形式为const char * xxx
    (3)rodata是在多个进程间共享的

  7. 文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间


全局、局部、静态全局、静态局部变量

全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区

  1. 全局变量 关键字:global整个工程 内都可以访问,只能定义一次。是静态存储方式,存储在 静态存储区,全局变量只需在一个源文件中定义,任意文件的任意函数都可以修改全局变量 。如果全局变量定义在源文件a中,其他文件想要使用这个全局变量,需要用extern声明一下。
    如果一个C程序包括两个文件,在两个文件中都需要用到同一个外部变量NUM,此时不能分别在两个文件中各自定义一个外部变量NUM,否则在进行程序链接是会出现 重复定义的错误;正确的做法是:在任一文件中定义全局变量NUM,而在另一文件中用 extern 对NUM 作 “外部变量声明”,即 extern NUM;这样在编译和链接时,系统就会知道NUM有 外部链接,可以从别处找到已定义的NUM,然后将NUM的作用域进行扩展

  2. 局部变量:局部区域内有用,位于栈上。

  3. 静态static的含义

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值