Linux:地址分区——常量区、全局区、堆区、栈区

9 篇文章 0 订阅
  • 平台:Linux。本次实验是基于Linux平台,结论和其他平台略有出入。
  • 实验内容:大致验证地址空间的各个分区。

目录

结论如图:

结论说明,由低地址向高地址:

结论验证:


结论如图:

结论说明,由低地址向高地址:

  • 代码区:存放程序的正文代码。
  • 常量区:编译时,以地址的形式编码于指令中。比如字符串常量、const修饰的全局变量。(const修饰的局部变量依然在栈上
  • 全局区:静态变量区和全局变量区统称全局数据区,存放全局变量、静态变量 (static)(全局和局部静态变量)。这部分变量中,初始化了的数据、未初始化的数据,它们之间是有地址大小关系的,初始化数据的地址相对较低。
  • 堆区:C语言使用malloc、realloc、calloc开辟的内存空间就在堆上,地址增长方向是由低到高,可用空间较大。
  • 栈区:存放函数的入口参数、返回值,局部变量、const定义的局部变量,以及函数调用开辟的栈帧,地址增长方向是由高到低,与堆相反。
  • 命令行参数、环境变量:不仅存放Linux中的命令行参数、环境变量,还有main函数的命令行参数表、环境变量表,它们的地址都要高于栈区。

结论验证:

        编辑源文件代码内容如下:

int g_val = 90;
int ung_val;
int main(int argc,char* argv[],char* env[])
{
  //代码区
  printf("code text addr:%p\n",main);
  //初始化数据
  printf("init gloabl vari addr:%p\n",&g_val);
  //未初始化数据
  printf("uninit gloabl vari addr:%p\n",&ung_val);
  //堆区
  char* heap0 = (char*)malloc(10);
  char* heap1 = (char*)malloc(10);
  char* heap2 = (char*)malloc(10);
  char* heap3 = (char*)malloc(10);
  printf("heap addr:%p\n",heap0);
  printf("heap addr:%p\n",heap1);
  printf("heap addr:%p\n",heap2);
  printf("heap addr:%p\n",heap3);
  //静态变量
  static int s_i = 3;
  printf("static vari addr:%p\n",&s_i);
  //栈区
  printf("stack addr:%p\n",&heap0);
  printf("stack addr:%p\n",&heap1);
  printf("stack addr:%p\n",&heap2);
  printf("stack addr:%p\n",&heap3);
  //命令行参数表,即main的隐形参数
  for(int i = 0;argv[i];++i)
  {
    printf("&argv[%d] = %p\n",i,argv+ i);
  }
  //环境变量表
  for(int i = 0;env[i];++i)
  {
    printf("&env[%d] = %p\n",i,env + i);
  }
  //命令行参数,即数组每个元素的值,字符串首字符地址
  for(int i = 0;argv[i];++i)
  {
    printf("argv[%d] = %p\n",i,argv[i]);
  }
  //环境变量,字符串首字符地址
  for(int i = 0;env[i];++i)
  {
    printf("env[%d] = %p\n",i,env[i]);
  }

  return 0;
}

        注意由于要打印命令行参数,故需要加一些选项。运行结果如下,与结论相符合。

[euto@VM-4-13-centos 24926]$ ./myprocess -a -b -c -d
代码区
code text addr:0x4005bd
初始化数据
init gloabl vari addr:0x601044
未初始化数据
uninit gloabl vari addr:0x601050
堆区
heap addr:0x10e3010
heap addr:0x10e3030
heap addr:0x10e3050
heap addr:0x10e3070
静态变量
static vari addr:0x601048
栈区
stack addr:0x7ffd4f17ca88
stack addr:0x7ffd4f17ca80
stack addr:0x7ffd4f17ca78
stack addr:0x7ffd4f17ca70
命令行参数表
&argv[0] = 0x7ffd4f17cb88
&argv[1] = 0x7ffd4f17cb90
&argv[2] = 0x7ffd4f17cb98
&argv[3] = 0x7ffd4f17cba0
&argv[4] = 0x7ffd4f17cba8
环境变量表
&env[0] = 0x7ffd4f17cbb8
&env[1] = 0x7ffd4f17cbc0
&env[2] = 0x7ffd4f17cbc8
&env[3] = 0x7ffd4f17cbd0
&env[4] = 0x7ffd4f17cbd8
&env[5] = 0x7ffd4f17cbe0
&env[6] = 0x7ffd4f17cbe8
&env[7] = 0x7ffd4f17cbf0
&env[8] = 0x7ffd4f17cbf8
&env[9] = 0x7ffd4f17cc00
&env[10] = 0x7ffd4f17cc08
&env[11] = 0x7ffd4f17cc10
&env[12] = 0x7ffd4f17cc18
&env[13] = 0x7ffd4f17cc20
&env[14] = 0x7ffd4f17cc28
&env[15] = 0x7ffd4f17cc30
&env[16] = 0x7ffd4f17cc38
&env[17] = 0x7ffd4f17cc40
&env[18] = 0x7ffd4f17cc48
&env[19] = 0x7ffd4f17cc50
&env[20] = 0x7ffd4f17cc58
&env[21] = 0x7ffd4f17cc60
&env[22] = 0x7ffd4f17cc68
&env[23] = 0x7ffd4f17cc70
命令行参数
argv[0] = 0x7ffd4f17d77a
argv[1] = 0x7ffd4f17d786
argv[2] = 0x7ffd4f17d789
argv[3] = 0x7ffd4f17d78c
argv[4] = 0x7ffd4f17d78f
环境变量
env[0] = 0x7ffd4f17d792
env[1] = 0x7ffd4f17d7a8
env[2] = 0x7ffd4f17d7c0
env[3] = 0x7ffd4f17d7cb
env[4] = 0x7ffd4f17d7db
env[5] = 0x7ffd4f17d7e9
env[6] = 0x7ffd4f17d80a
env[7] = 0x7ffd4f17d81d
env[8] = 0x7ffd4f17d827
env[9] = 0x7ffd4f17d86b
env[10] = 0x7ffd4f17de07
env[11] = 0x7ffd4f17de21
env[12] = 0x7ffd4f17de7d
env[13] = 0x7ffd4f17de98
env[14] = 0x7ffd4f17dea8
env[15] = 0x7ffd4f17deb0
env[16] = 0x7ffd4f17dec0
env[17] = 0x7ffd4f17decd
env[18] = 0x7ffd4f17defc
env[19] = 0x7ffd4f17df1f
env[20] = 0x7ffd4f17df91
env[21] = 0x7ffd4f17dfb0
env[22] = 0x7ffd4f17dfc6
env[23] = 0x7ffd4f17dfd4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值