Каково обоснование адресов этих локальных переменных? - PullRequest
0 голосов
/ 03 июня 2018

Я играл и смотрел на локальные переменные в памяти.К моему удивлению, я не понимаю, почему адреса такие, какие они есть.

Вот пример программы

 int main() {
   int my_array[30]; 
   int a = 10; 
   int b = 11; 
   char h = 'A'; 
   char temp_array[10];
   int c = 12; 
 }

Я ожидал, что в кадре стека будут все эти переменные по порядку.При печати GDB адреса памяти показывают, что это не так!

(gdb) print &my_array
$4 = (int (*)[30]) 0x7fffffffde10
(gdb) print &a
$5 = (int *) 0x7fffffffde04
(gdb) print &b
$6 = (int *) 0x7fffffffde08
(gdb) print &h
$7 = 0x7fffffffde03 '/' <repeats 13 times>
(gdb) print &temp_array
$8 = (char (*)[10]) 0x7fffffffde90
(gdb) print &c
$9 = (int *) 0x7fffffffde0c

На основе этих адресов памяти кадр стека фактически равен:

temp_array <--- Highest memory address
---------
my_array
---------
c
---------
b
---------
a
---------
h    <---- Lowest memory address

Почему это так?Я предполагаю, что мой компилятор (gcc) организовывает это таким образом по причине, может кто-то сказать мне, почему?Спасибо.Изменить: это может быть для выравнивания байтов или что-то?Сначала идут буферы, затем целые числа, затем символы, и, как говорится, почему вместо CBC идет CBA?

1 Ответ

0 голосов
/ 03 июня 2018

Почему это так?

Компилятор может свободно размещать кадр стека по своему усмотрению.Этот макет может меняться от версии к версии, от компилятора к компилятору и с разными уровнями оптимизации.

Чтобы узнать точно , почему именно этот конкретный макет был выбран, вам придется пройти через GCCпоскольку он выполняет компоновку.

В общем, GCC может попытаться минимизировать дыры / отступы между переменными (это раздражает конечных пользователей, когда их программы заканчиваются в стеке).Это объясняет, почему все int переменные были выделены вместе - они имеют одинаковое требование выравнивания и могут размещаться одна за другой без пропусков.

...