程序在内存中的分布

在现代的操作系统中,当我们说到内存,往往需要分两部分来讲:物理内存和虚拟内存。从硬件上讲,虚拟空间是CPU内部的寻址空间,位于MMU之前,物理空间是总线上的寻址空间,是经过MMU转换之后的空间。

一般我们所说的程序在内存中的分布指的就是程序在虚拟内存中的存储方式。

从低地址到高地址,可分为下面几段: 
预留内存地址
(操作系统维护的内存地址,不可访问) 
程序代码区(只读,存代码和一些其他的东西); 
data段(存初始化的全局变量和static变量,另外还有文字常量区,常量字符串就是放在这里,程序结束后有系统释放); 
bss段(存未初始化的全局变量和static变量); 
由低地址向高地址增长,一般new和malloc分配,由程序员分配释放);
共享库文件(调用的库文件,位于堆和栈之间);
 
由高地址向低地址增长,和堆的增长方式相对,对不同的OS来说,栈的初始大小有规定,可以修改,目前默认一般为2M,由编译器自动分配释放); 
再上面存的都是操作系统和内核调用的一些内存地址

如图所示:

C语言程序内存中的分布可以分为多个区域,这些区域各自承担不同的职责,以支持程序的执行和数据存储需求。以下是C语言程序内存分布的主要组成部分及其特点: ### 栈(Stack) 栈区用于存储函数调用过程中产生的局部变量和函数参数。这一区域的内存管理由编译器自动完成,遵循后进先出的原则。当一个函数被调用时,该函数的局部变量和参数会被压入栈中;当函数调用结束,这些数据会被弹出栈,释放相应的内存空间[^1]。 ### 堆(Heap) 堆区用于动态内存分配,程序员需要显式地请求分配和释放内存。使用`malloc`、`calloc`、`realloc`等函数分配内存,使用`free`函数释放内存。堆区的管理较为灵活,但也容易因管理不当而造成内存泄漏[^2]。 ### BSS段(Uninitialized Data Segment) BSS段用于存储未初始化的全局变量和静态变量。如果一个全局变量或静态变量没有被显式初始化,或者被初始化为0,它们将被放置在这个段中。BSS段不占用可执行文件的空间,其内容由操作系统在程序启动时初始化为零[^3]。 ### 数据段(Data Segment) 数据段用于存储已初始化的全局变量和静态变量。这部分数据在程序启动时已经被赋予了初始值,因此它们占用可执行文件的空间,程序启动时会从可执行文件加载这些初始值[^3]。 ### 代码区(Text Segment) 代码区,也称为文本段,用于存储程序的机器指令。这是程序的可执行部分,包含了程序的所有函数和方法的机器码。代码区通常是只读的,以防止程序意外修改自身的指令[^2]。 ### 示例代码 以下是一个简单的C语言程序示例,展示了不同类型的变量如何分布在上述内存区域中: ```c #include <stdio.h> #include <stdlib.h> int globalVar = 10; // Data segment static int staticVar; // BSS segment int main() { int localVar = 20; // Stack segment int *heapVar = malloc(sizeof(int)); // Heap segment *heapVar = 30; printf("globalVar: %d, staticVar: %d, localVar: %d, heapVar: %d\n", globalVar, staticVar, localVar, *heapVar); free(heapVar); // Free heap memory return 0; } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值