Адрес памяти переменных C - PullRequest
0 голосов
/ 01 декабря 2011

это мой вопрос викторины (предупреждение, длинный):

Учитывая следующую программу, измените порядок строк printf так, чтобы значения, которые выводятся на печать, сортировались из от наименьшего к наибольшему, если он скомпилирован и работает на архитектуре Sun SPARC. Эти строки выводят шестнадцатеричный адрес различные части программы (не назначенные значения) с указателем формата printf ()% p (указатель).

#include <stdio.h> 
#include <stdlib.h> 
int a = 420; 
void foo() { 
    int b; 
    /* 1 */ printf( "b --> %p\n", &b ); 
} 

int 
    main( int argc, char *argv[] ) { 
        int c; 
        int d = 42; 
        static int e; 
        /* 2 */ (void) printf( "foo() --> %p\n", foo ); 
        /* 3 */ (void) printf( "e --> %p\n", &e ); 
        /* 4 */ (void) printf( "malloc --> %p\n", malloc(420) ); 
        foo(); 
        /* 5 */ (void) printf( "d --> %p\n", &d ); 
        /* 6 */ (void) printf( "argv --> %p\n", &argv ); 
        /* 7 */ (void) printf( "a --> %p\n", &a ); 
        /* 8 */ (void) printf( "c --> %p\n", &c ); 
        /* 9 */ (void) printf( "argc --> %p\n", &argc ); 
    return 0; 
} 

Я запустил эту программу на C и получил следующие напечатанные значения:

2  foo() --> 10594
3  e --> 2099c
4  malloc --> 209a8
1  b --> ffbff1b4
5  d --> ffbff228
6  argv --> ffbff288
7  a --> 20974
8  c --> ffbff22c
9  argc --> ffbff284

Мой вопрос хорошо .... почему? Я попытался сделать это вручную, вспомнив, где была сохранена каждая переменная (стек, BSS, данные и т. Д.), И попытался упорядочить их, сказав, что это порядок переменных, от малой памяти до большой памяти:

Так это должно быть организовано от наименьшего к наименьшему?

LOW MEMORY - text (labels, function names):
2 - foo
data (initialized global/static vars):
7 - a
BSS ( initialized global/static vars:
3 - e
stack (local vars):
9 - argc
6 - argv[]
8 - c
5 - d
1 - b
4 - ptr returned by malloc
HIGH MEMORY

Если это противоречит напечатанным значениям памяти, я не знаю почему, кто-то возражает объяснить, почему? Спасибо :)!

1 Ответ

2 голосов
/ 01 декабря 2011

Единственный конфликт - в области стека.

Это зависит от системы, если размер стека увеличивается с более высоких адресов на более низкие (что является обычным случаем) или другим способом.

Нав нижней части стека находятся argc и argv, затем c и d, а затем b.

Поскольку аргументы помещаются в стек «неправильным образом»,сначала нажимается argv, затем argc, давая argc меньший адрес.То же самое верно для c и d, очевидно;но я думаю, что компилятор свободен выбирать, куда помещать локальные переменные.

b имеет наименьший адрес, потому что он выдвигается очень поздно.

Кроме того, ptr, возвращаемый malloc() не в стеке, а в куче, которая начинается сразу после области BSS.

Это делает решение

LOW MEMORY
text (labels, function names):
2 - foo
data (initialized global/static vars):
7 - a
BSS (initialized global/static vars):
3 - e
heap:
4 - ptr returned by malloc
stack (local vars):
1 - b
5 - d
8 - c
9 - argc
6 - argv[]
HIGH MEMORY

Причиной этого неинтуитивного порядка передачи аргументов являетсяпотому что есть опция для переменных параметров длины.Возможно, вам известна функция printf(), где все эти вызовы действительны:

printf("Hello\n");
printf("Hello %s\n", name);
printf("Hello User #%d (%s)\n", nr, name);

Только число вызывающих абонентов знает число переменных.Вызываемая функция знает вершину стека и хочет иметь определенное смещение к первым аргументам.Таким образом, единственный вариант - поместить первые аргументы на вершину стека, таким образом начав толкать от последнего к первому.Зачастую данные фактически не передаются, но указатель стека уменьшается вручную, а память, зарезервированная таким образом, заполняется впоследствии.

...