6

为什么返回的指针地址的十六进制值总是按降序排列?例如这里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新手

4

5 回答 5

6

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


                         /------------------\  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 语言规范的角度来看,随后分配的变量的内存位置顺序是未指定的。因此,这取决于...

于 2012-09-15T15:13:08.167 回答
3

你不能对此做出任何假设。对于某些编译器、某些体系结构和某些编译器开关,您可能会看到这种行为,即局部变量被分配到连续较低的堆栈地址,但优化和其他因素可以改变这种行为。

于 2012-09-15T14:34:31.123 回答
2

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

更多关于这里

于 2012-09-15T14:36:03.007 回答
0

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

于 2012-09-15T14:35:36.423 回答
0

一个粗略和半准确的解释(忽略有关堆栈和堆差异的详细信息)是:您希望最小化内存中静态分配的内容与您需要动态分配的内容的冲突。当你的程序运行时,动态的东西通常会变大。为了最大化分配动态内容的容量,静态内容和动态内容通常分配在内存空间的两端,动态内容向静态内容增长。在您的特定情况下,您的编译器似乎将静态内容加载到内存中,并将动态内容从内存的末尾向内存的开头(在静态内容的方向)增长。

于 2012-09-15T14:40:33.953 回答