C语言 - 常量和变量的存储位置


C语言 - 常量和变量的存储位置

〇、环境

语言 C
编译器 gcc
编译环境 x86_64-linux-gnu

一、常量和变量的存储位置

1.1 实验方法

静态观察:对编译得到的可执行文件进行分析
动态观察:运行时获取变量的地址,并分析变量在进程地址空间的位置

1.2 示例程序

示例程序1

#include <stdio.h>
#include <unistd.h>

static int local_static_uninit;
static int local_static_init = 0x88;
static int localarr_static_uninit[1024];
static int localarr_static_init[1024] = {1,2,3};

int global_uninit;
int gloabl_init = 0x88;
int globalarr_uninit[1024];
int globalarr_init[1024] = {1,2,3};

int add(int a, int b)
{
  static int infun_static_uninit;
  static int infun_static_init = 0x88;
  static int infunarr_static_uninit[1024];
  static int infunarr_static_init[1024] = {1,2,3};

  int c;
  int d = 0;
  int e = a + b;

  printf (
    "&local_static_uninit=%p\n"
    "&local_static_init=%p\n"
    "&localarr_static_uninit[0]=%p\n"
    "&localarr_static_init[0]=%p\n"
    "&global_uninit=%p\n"
    "&gloabl_init=%p\n"
    "&globalarr_uninit[0]=%p\n"
    "&globalarr_init[0]=%p\n"
    "&infun_static_uninit=%p\n"
    "&infun_static_init=%p\n"
    "&infunarr_static_uninit[0]=%p\n"
    "&infunarr_static_init[0]=%p\n"
    "&a=%p\n"
    "&b=%p\n"
    "&c=%p\n"
    "&d=%p\n"
    ,
    &local_static_uninit,
    &local_static_init,
    &localarr_static_uninit[0],
    &localarr_static_init[0],
    &global_uninit,
    &gloabl_init,
    &globalarr_uninit[0],
    &globalarr_init[0],
    &infun_static_uninit,
    &infun_static_init,
    &infunarr_static_uninit[0],
    &infunarr_static_init[0],
    &a, &b, &c, &d
  );

  while (1)
  {
    sleep (5);
  }

  return e;
}

int main()
{
  add(1,2);
  return 0;
}

文件布局:

运行输出:

./a.out
&local_static_uninit=0x6040e0
&local_static_init=0x601060
&localarr_static_uninit[0]=0x604100
&localarr_static_init[0]=0x601080
&global_uninit=0x606120
&gloabl_init=0x602080
&globalarr_uninit[0]=0x606140
&globalarr_init[0]=0x6020a0
&infun_static_uninit=0x605100
&infun_static_init=0x6030a0
&infunarr_static_uninit[0]=0x605120
&infunarr_static_init[0]=0x6030c0
&a=0x7ffd0ee30b1c
&b=0x7ffd0ee30b18
&c=0x7ffd0ee30b2c
&d=0x7ffd0ee30b30

进程地址布局:

cat /proc/2446/maps
00400000-00401000 r-xp 00000000 fc:00 130819 /home/ttt/test/a.out
00600000-00601000 r--p 00000000 fc:00 130819 /home/ttt/test/a.out
00601000-00605000 rw-p 00001000 fc:00 130819 /home/ttt/test/a.out
00605000-00608000 rw-p 00000000 00:00 0
007cf000-007f0000 rw-p 00000000 00:00 0 [heap]
7f54a3458000-7f54a3618000 r-xp 00000000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so
7f54a3618000-7f54a3818000 ---p 001c0000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so
7f54a3818000-7f54a381c000 r--p 001c0000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so
7f54a381c000-7f54a381e000 rw-p 001c4000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so
7f54a381e000-7f54a3822000 rw-p 00000000 00:00 0
7f54a3822000-7f54a3848000 r-xp 00000000 fc:00 659993 /lib/x86_64-linux-gnu/ld-2.23.so
7f54a3a3c000-7f54a3a3f000 rw-p 00000000 00:00 0
7f54a3a47000-7f54a3a48000 r--p 00025000 fc:00 659993 /lib/x86_64-linux-gnu/ld-2.23.so
7f54a3a48000-7f54a3a49000 rw-p 00026000 fc:00 659993 /lib/x86_64-linux-gnu/ld-2.23.so
7f54a3a49000-7f54a3a4a000 rw-p 00000000 00:00 0
7ffd0ee11000-7ffd0ee32000 rw-p 00000000 00:00 0 [stack]
7ffd0eff3000-7ffd0eff6000 r--p 00000000 00:00 0 [vvar]
7ffd0eff6000-7ffd0eff8000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

1.3 结果分析

1.3.1 运行时结果

  • 源文件中的全局变量,包括普通全局变量、静态全局变量,不论是否初始化,均在程序段(可写数据段)
  • 函数内部的静态变量,不论是否初始化,均在程序段(可写数据段)。(和全局变量一致)
  • 函数内部的局部变量,函数传参,均在栈段。

1.3.2 静态分析结果

说明一点,未初始化的全局变量(包括函数内静态变量)位于.bss段,并不占用可执行文件的空间。以后再表。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM