图说 bss段 text段 data段 rodata段 栈 堆
1.理论上程序编译出来后,各个段的分布
程序在执行后,虚拟内存分布,如下图:

下面从低地址到高地址,先分别说明下每个段的意义:
1.受保护区
受保护区,是用户(程序猿)不能访问的地址,一般为 0-4k。
我们平时写程序的,初始化一个指针
char *p = NULL;
这个NULL就是指向的受保护区,0 地址。
2.txt段
.txt段 是代码段,比如我们的程序源码就放在这块区域
当然,如果有动态链接库,库代码不是放在这里的,是放在共享库里的。
这里面的地址是绝对地址。
3.rodata段
.rodata段 是 只读数据段,比如我们用const修饰的值就是放在这个区域的。
const int a[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
table a 就是放在 .rodata段的
4.data段
.data段 是数据段,存放了已经初始化的全局变量,以及初始化全局静态变量,初始化的局部静态变量等。
int g_init_v = 1;
static int static_init_v = 1;
static int static_uinit_v;
初始化的全局变量,已经初始化和未初始化的静态变量都在这个段,初始化的局部静态变量。
5.bss段
.bss段 是未初始化的全局变量以及未初始化的静态局部变量。
int g_uinit_v;
6.堆
堆,程序员可以用来分配内存的空间,使用malloc分配。
/* mallloc */
int *malloc_v = malloc(10);
在创建进程的时候,会为进程分配多大的堆。
7.共享库
共享库,在调用了共享库的可执行程序里面,共享库放在这个位置。
前面有写过一篇文章,如果需要,可以看看共享库的制作与使用。
https://blog.youkuaiyun.com/acdefghb/article/details/105774084
8.栈
栈,程序执行过程中,程序用来存放临时变量和函数返回值的区域。
由系统分配和回收。
在进程创建的时候,每个进程/线程都有自己独立的栈空间。
9.命令行和环境变量
环境变量:就是我们linux的环境变量,env
命令行参数,比如
int main(int argc, char *argv[])
这里面argv所带的参数。
2.利用下面的例子说明
//memery_test_n.c
#include <stdio.h>
#include <stdlib.h>
/* 初始化全局变量 */
int g_init_v = 1;
/* 未初始化全局变量 */
int g_uinit_v;
/* 初始化静态全局变量 */
static int g_s_init_v = 1;
/* 未初始化静态全局变量 */
static int g_s_uinit_v;
/* 初始化全局数组 并用const 修饰 */
const int g_table1_init[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
/* 初始化全局变量 不用const 修饰 */
int g_table2_init[] = {
11, 21, 31, 41, 51, 61, 71, 81, 91, 101};
/* 全局字符串 */
char *g_str =

本文深入解析程序编译后的段分布,包括代码段(.txt),数据段(.data),未初始化数据段(.bss),只读数据段(.rodata),以及堆、栈、共享库等区域的功能与变量存放规则。
最低0.47元/天 解锁文章
2454

被折叠的 条评论
为什么被折叠?



