Всегда ли упорядочен адрес памяти последовательно объявленных переменных по убыванию?
Почему шестнадцатеричное значение возвращаемого адреса указателя всегда в порядке убывания? например здесь int a
было объявлено ранее int d
поэтому его адрес всегда оказывается больше d
и то же самое для &b
,&e
а также &c
,&f
Я хочу знать, что это фиксированное поведение или это зависит от компилятора? я использую gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-1
)
#include<stdio.h>
int main(void){
int a=1;
int d=1;
char b='a' ;
char e='a';
float c=1.0;
float f=1.0;
printf("a=%p\nd=%p\nb=%p\ne=%p\nc=%p\nf=%p\n",&a,&d,&b,&e,&c,&f);
if (&a>&d)
printf("&a>&d\n");
else
{printf("&a<&d");
}
if (&a>&d && &b>&e && &c>&f)
printf("addresses are in descending order");
else{
printf("false");
}
return 0;
}
выход:
a=0xbfc6bd98 //a>d
d=0xbfc6bd94
b=0xbfc6bd9f //b>e
e=0xbfc6bd9e
c=0xbfc6bd90 //c>f
f=0xbfc6bd8c
&a>&d
addresses are in descending order
PS: я новичок в c
5 ответов
Обнаружил, что это хорошо объяснено в " Разбить стек ради удовольствия и прибыли" Алефа Первого. Извлечены самые актуальные детали.
/------------------\ lower | | memory | Text | addresses | | |------------------| | (Initialized) | | Data | | (Uninitialized) | |------------------| | | | Stack | higher | | memory \------------------/ addresses Fig. 1 Process Memory Regions
[...]
The stack consists of logical stack frames that are pushed when calling a function and popped when returning. A stack frame contains the parameters to a function, its local variables, and the data necessary to recover the previous stack frame, including the value of the instruction pointer at the time of the function call. Depending on the implementation the stack will either grow down (towards lower memory addresses), or up. In our examples we'll use a stack that grows down. This is the way the stack grows on many computers including the Intel, Motorola, SPARC and MIPS processors.
[...]
Let us see what the stack looks like in a simple example: example1.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } void main() { function(1,2,3); } ------------------------------------------------------------------------------
[...]
With that in mind our stack looks like this when function() is called (each space represents a byte): bottom of top of memory memory buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] top of bottom of stack stack
Как видите, новые (локальные) переменные помещаются поверх стека. В зависимости от дизайна архитектуры, стек увеличивается в сторону более высоких адресов памяти или в сторону более низких адресов памяти, последний в вашем случае.
С точки зрения спецификации языка Си, порядок расположения в памяти распределенных впоследствии переменных не определен. Поэтому это зависит...
Вы не можете делать никаких предположений по этому поводу. С некоторыми компиляторами, некоторыми архитектурами и некоторыми переключателями компилятора вы можете видеть это поведение, то есть локальные переменные, размещаемые по последовательно меньшим адресам стека, но оптимизация и другие факторы могут изменить это поведение.
Переменные, адрес которых вы сравниваете, являются локальными переменными, расположенными в стеке. Теперь способ увеличения стека (вверх или вниз) зависит от архитектуры. Похоже, в вашем случае стек растет вниз, поэтому вы видите уменьшение адресов.
Грубое и полуточное объяснение (без учета подробностей о различиях со стеками и кучами) таково: вы хотите минимизировать статически распределенные данные в памяти, конфликтующие с данными, которые необходимо динамически распределять. Динамические вещи обычно увеличиваются в размерах при запуске вашей программы. Чтобы максимизировать возможности выделения динамических элементов, статические элементы и динамические элементы обычно располагаются на противоположных концах пространства памяти, а динамические элементы растут по направлению к статическим элементам. В вашей конкретной ситуации это выглядит так, как будто ваш компилятор загружает статический материал с низким объемом памяти и увеличивает динамический материал с конца до начала вашей памяти (в направлении вашего статического материала).