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