C language variable memory layout

 

This article tests the layout memory distribution of C language variables and constants in different situations in the Linux environment.

Architecture:x86_64

Operation system:ubuntu 18.04

edit:    gcc 7.4.0

variable

Initialized

The global variable var is initialized to 1:

int var = 1;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     8: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 var
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000c 00  AX  0   0  1
  [ 2] .rela.text        RELA            0000000000000000 0001b8 000018 18   I  9   1  8
  [ 3] .data             PROGBITS        0000000000000000 00004c 000004 00  WA  0   0  4
  [ 4] .bss              NOBITS          0000000000000000 000050 000000 00  WA  0   0  1
  [ 5] .comment          PROGBITS        0000000000000000 000050 00002c 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        0000000000000000 00007c 000000 00      0   0  1
  [ 7] .eh_frame         PROGBITS        0000000000000000 000080 000038 00   A  0   0  8
  [ 8] .rela.eh_frame    RELA            0000000000000000 0001d0 000018 18   I  9   7  8
  [ 9] .symtab           SYMTAB          0000000000000000 0000b8 0000f0 18     10   8  8
  [10] .strtab           STRTAB          0000000000000000 0001a8 000010 00      0   0  1
  [11] .shstrtab         STRTAB          0000000000000000 0001e8 000059 00      0   0  1

int var =1 After compilation, in the .data section of the relocatable object file


The local variable var is initialized to 1:

static int var = 1;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    3 var
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000c 00  AX  0   0  1
  [ 2] .rela.text        RELA            0000000000000000 0001b8 000018 18   I  9   1  8
  [ 3] .data             PROGBITS        0000000000000000 00004c 000004 00  WA  0   0  4
  [ 4] .bss              NOBITS          0000000000000000 000050 000000 00  WA  0   0  1
  [ 5] .comment          PROGBITS        0000000000000000 000050 00002c 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        0000000000000000 00007c 000000 00      0   0  1
  [ 7] .eh_frame         PROGBITS        0000000000000000 000080 000038 00   A  0   0  8
  [ 8] .rela.eh_frame    RELA            0000000000000000 0001d0 000018 18   I  9   7  8
  [ 9] .symtab           SYMTAB          0000000000000000 0000b8 0000f0 18     10   9  8
  [10] .strtab           STRTAB          0000000000000000 0001a8 000010 00      0   0  1
  [11] .shstrtab         STRTAB          0000000000000000 0001e8 000059 00      0   0  1

static int var =1 After compilation, in the .data section of the relocatable object file


The global variable var is initialized to 0:

int var = 0;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     8: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 var
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x240:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000c 00  AX  0   0  1
  [ 2] .rela.text        RELA            0000000000000000 0001b0 000018 18   I  9   1  8
  [ 3] .data             PROGBITS        0000000000000000 00004c 000000 00  WA  0   0  1
  [ 4] .bss              NOBITS          0000000000000000 00004c 000004 00  WA  0   0  4
  [ 5] .comment          PROGBITS        0000000000000000 00004c 00002c 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        0000000000000000 000078 000000 00      0   0  1
  [ 7] .eh_frame         PROGBITS        0000000000000000 000078 000038 00   A  0   0  8
  [ 8] .rela.eh_frame    RELA            0000000000000000 0001c8 000018 18   I  9   7  8
  [ 9] .symtab           SYMTAB          0000000000000000 0000b0 0000f0 18     10   8  8
  [10] .strtab           STRTAB          0000000000000000 0001a0 000010 00      0   0  1
  [11] .shstrtab         STRTAB          0000000000000000 0001e0 000059 00      0   0  1

int var =0 After compilation, in the .bss section of the relocatable object file


Local variables are initialized to 0:

static int var = 0;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 var
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x240:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000c 00  AX  0   0  1
  [ 2] .rela.text        RELA            0000000000000000 0001b0 000018 18   I  9   1  8
  [ 3] .data             PROGBITS        0000000000000000 00004c 000000 00  WA  0   0  1
  [ 4] .bss              NOBITS          0000000000000000 00004c 000004 00  WA  0   0  4
  [ 5] .comment          PROGBITS        0000000000000000 00004c 00002c 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        0000000000000000 000078 000000 00      0   0  1
  [ 7] .eh_frame         PROGBITS        0000000000000000 000078 000038 00   A  0   0  8
  [ 8] .rela.eh_frame    RELA            0000000000000000 0001c8 000018 18   I  9   7  8
  [ 9] .symtab           SYMTAB          0000000000000000 0000b0 0000f0 18     10   9  8
  [10] .strtab           STRTAB          0000000000000000 0001a0 000010 00      0   0  1
  [11] .shstrtab         STRTAB          0000000000000000 0001e0 000059 00      0   0  1

static int var =0 After compilation, in the .bss section of the relocatable object file

Uninitialized

Global variable var is not initialized:

int var;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     8: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM var
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 say

After int var is compiled, it is in the .COMMON section of the relocatable object file.


Local variable not initialized:

static int var;

int say() {
    return var;
}

 

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 var
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x240:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000c 00  AX  0   0  1
  [ 2] .rela.text        RELA            0000000000000000 0001b0 000018 18   I  9   1  8
  [ 3] .data             PROGBITS        0000000000000000 00004c 000000 00  WA  0   0  1
  [ 4] .bss              NOBITS          0000000000000000 00004c 000004 00  WA  0   0  4
  [ 5] .comment          PROGBITS        0000000000000000 00004c 00002c 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        0000000000000000 000078 000000 00      0   0  1
  [ 7] .eh_frame         PROGBITS        0000000000000000 000078 000038 00   A  0   0  8
  [ 8] .rela.eh_frame    RELA            0000000000000000 0001c8 000018 18   I  9   7  8
  [ 9] .symtab           SYMTAB          0000000000000000 0000b0 0000f0 18     10   9  8
  [10] .strtab           STRTAB          0000000000000000 0001a0 000010 00      0   0  1
  [11] .shstrtab         STRTAB          0000000000000000 0001e0 000059 00      0   0  1

static int var After compilation, in the .bss section of the relocatable target file


constant

Initialized

The global constant var is initialized:

const int var = 0;

int say() {
    return var;
}

 root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 11 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     9: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 var
    10: 0000000000000000    11 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000b 00  AX  0   0  1
  [ 2] .data             PROGBITS        0000000000000000 00004b 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          0000000000000000 00004b 000000 00  WA  0   0  1
  [ 4] .rodata           PROGBITS        0000000000000000 00004c 000004 00   A  0   0  4
  [ 5] .comment          PROGBITS        0000000000000000 000050 00002c 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        0000000000000000 00007c 000000 00      0   0  1
  [ 7] .eh_frame         PROGBITS        0000000000000000 000080 000038 00   A  0   0  8
  [ 8] .rela.eh_frame    RELA            0000000000000000 0001d0 000018 18   I  9   7  8
  [ 9] .symtab           SYMTAB          0000000000000000 0000b8 000108 18     10   9  8
  [10] .strtab           STRTAB          0000000000000000 0001c0 000010 00      0   0  1
  [11] .shstrtab         STRTAB          0000000000000000 0001e8 00005c 00      0   0  1

const int var = 0 After compilation, in the .rodata section of the relocatable object file


 

The local constant var is initialized:

static const int var = 0;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 11 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     6: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 var
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     9: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
    10: 0000000000000000    11 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 12 section headers, starting at offset 0x248:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000b 00  AX  0   0  1
  [ 2] .data             PROGBITS        0000000000000000 00004b 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          0000000000000000 00004b 000000 00  WA  0   0  1
  [ 4] .rodata           PROGBITS        0000000000000000 00004c 000004 00   A  0   0  4
  [ 5] .comment          PROGBITS        0000000000000000 000050 00002c 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        0000000000000000 00007c 000000 00      0   0  1
  [ 7] .eh_frame         PROGBITS        0000000000000000 000080 000038 00   A  0   0  8
  [ 8] .rela.eh_frame    RELA            0000000000000000 0001d0 000018 18   I  9   7  8
  [ 9] .symtab           SYMTAB          0000000000000000 0000b8 000108 18     10  10  8
  [10] .strtab           STRTAB          0000000000000000 0001c0 000010 00      0   0  1
  [11] .shstrtab         STRTAB          0000000000000000 0001e8 00005c 00      0   0  1

static const int var = 0 After compilation, in the .rodata section of the relocatable object file


Uninitialized

Global constant var is not initialized:

const int var;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     8: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM var
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 say

const int var After compilation, in the .COMMON section of the relocatable object file


Local constant var is not initialized:

static const int var;

int say() {
    return var;
}

root@nemo-VirtualBox:~/workspace/learn# gcc -c  test.c
root@nemo-VirtualBox:~/workspace/learn# readelf -s -W test.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    3 var
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     9: 0000000000000000    11 FUNC    GLOBAL DEFAULT    1 say

root@nemo-VirtualBox:~/workspace/learn# readelf -S -W test.o
There are 11 section headers, starting at offset 0x220:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000b 00  AX  0   0  1
  [ 2] .data             PROGBITS        0000000000000000 00004b 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          0000000000000000 00004c 000004 00  WA  0   0  4
  [ 4] .comment          PROGBITS        0000000000000000 00004c 00002c 01  MS  0   0  1
  [ 5] .note.GNU-stack   PROGBITS        0000000000000000 000078 000000 00      0   0  1
  [ 6] .eh_frame         PROGBITS        0000000000000000 000078 000038 00   A  0   0  8
  [ 7] .rela.eh_frame    RELA            0000000000000000 0001b0 000018 18   I  8   6  8
  [ 8] .symtab           SYMTAB          0000000000000000 0000b0 0000f0 18      9   9  8
  [ 9] .strtab           STRTAB          0000000000000000 0001a0 000010 00      0   0  1
  [10] .shstrtab         STRTAB          0000000000000000 0001c8 000054 00      0   0  1

static const int var After compilation, in the .bss section of the relocatable object file


Summarize:

 

index definition Attributes scope Assignment location
1 int a = 1 variable overall situation any (except default empty value) .data
2 static int a = 1 variable local any (except default empty value) .data
3 int a = 0 variable overall situation Default empty value .bss
4 static int a = 0 variable local Default empty value .bss
5 int a variable overall situation Uninitialized .COMMON
6 static int a variable local Uninitialized .bss
7 const  int a = 0 constant overall situation any .rodata
8 static const int a = 0 constant local any .rodata
9 const int a constant overall situation Uninitialized .COMMON
10 static const int a constant local Uninitialized .bss
  • When a variable is initialized to a non-default null value, the compiler places it in the .data section (1, 2)
  • When a variable is initialized to the default null value, since .bss does not occupy space, the compiler optimizes and places it in the .bss section (3, 4)
  • Uninitialized global variables, because they are weak symbols, cannot determine the reference address at compile time, so they are placed in the .COMMON section, and the reference address is determined by the connector (5)
  • Uninitialized local variables. Since the scope is in this module, the compiler can determine the address referencing this variable. At the same time, because it is not initialized, it is placed in the .bss section (6)
  • After the constant is initialized, the compiler places it in .rodata (7,8)
  • Uninitialized global constants, because they are weak symbols, cannot determine the reference address at compile time, so they are placed in the .COMMON section, and the reference address is determined by the connector (9)
  • Uninitialized local constant. Since the scope is in this module, the compiler can determine the address referencing this constant. At the same time, because it is not initialized, it is placed in the .bss section (10)

question:

Since uninitialized local constants are placed in the .bss section, and the data in the .bss section can be modified, you can modify this value through a pointer, and then obtain the modified value through the pointer!

Example:

#include <stdio.h>

static const int var;

void set_var(int);

int get_var();

int main() {
    set_var(10);
    printf("%d\n", get_var());
}

void set_var(int v) {
    int *p = &var;
    *p = v;
}

int get_var() {
    int *p = &var;
    return *p;
}

root@nemo-VirtualBox:~/workspace/learn# gcc test.c
test.c: In function ‘set_var’:
test.c:19:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
     int *p = &var;
              ^
test.c: In function ‘get_var’:
test.c:24:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
     int *p = &var;
              ^
root@nemo-VirtualBox:~/workspace/learn# ./a.out 
10

 Because var is on .bss, we successfully modified the value of the local constant.


We make a small modification and assign an initial value of 0 to the local constant (it seems to be no different from the above), but. . .

#include <stdio.h>

static const int var = 0;

void set_var(int);

int get_var();

int main() {
    set_var(10);
    printf("%d\n", get_var());
}

void set_var(int v) {
    int *p = &var;
    *p = v;
}

int get_var() {
    int *p = &var;
    return *p;
}

root@nemo-VirtualBox:~/workspace/learn# gcc test.c
test.c: In function ‘set_var’:
test.c:19:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
     int *p = &var;
              ^
test.c: In function ‘get_var’:
test.c:24:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
     int *p = &var;
              ^
root@nemo-VirtualBox:~/workspace/learn# ./a.out 
Segmentation fault (core dumped) 

Because we assigned the local constant an initial value of 0, it was placed in the .rodata section by the compiler, and the data in the .rodata section is read-only. When writing, the operating system generates a segmentation fault. In order to avoid some strange errors, we recommend that constants must be assigned a value (even if the value is 0)

 

 

Guess you like

Origin blog.csdn.net/u013259665/article/details/100019121