连续声明的变量的内存地址顺序是否总是在下降?

时间:2012-09-15 14:31:47

标签: c pointers pointer-address

为什么返回的指针地址的十六进制值总是按降序排列? 例如,int a之前已声明int d,因此它的地址总是大于d&b&e和{{ 1}},&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;

}

PS:我是c的新手

5 个答案:

答案 0 :(得分:6)

Smashing The Stack For Fun And Profit, by Aleph One中找到了这个很好的解释。 提取最相关的部分。


                         /------------------\  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

如您所见,新的(本地)变量被推到堆栈顶部。根据体系结构的设计,堆栈会朝着更高的内存地址或更低的内存地址发展,后者就是你的情况。

从C语言规范的角度来看,未指定随后分配的变量的存储器位置的顺序。因此,这取决于......

答案 1 :(得分:3)

你不能对此作出任何假设。使用某些编译器,某些体系结构和某些编译器开关,可能会看到行为,即在连续降低堆栈地址,但优化和其他因素可以改变这种行为。

答案 2 :(得分:2)

您要比较的地址变量是堆栈上分配的所有局部变量。现在堆栈增长(向上或向下)的方式取决于架构。看起来在你的情况下,堆栈正在向下增长,所以你看到地址递减。

More on this here

答案 3 :(得分:0)

很多ABI定义了一个向下增长的堆栈。

答案 4 :(得分:0)

粗略和半准确的解释(忽略有关堆栈和堆的差异的详细信息)是:您希望最小化内存中静态分配的内容与您需要动态分配的内容冲突。当程序运行时,动态内容通常会增大。为了最大化分配动态内容的能力,静态内容和动态内容通常分配在内存空间的两端,动态内容会逐渐增加到静态内容。在您的特定情况下,您的编译器看起来像是在内存中加载静态内容并从内存到内存开头增加动态内容(朝向静态内容的方向)。