2012-09-15 30 views
3

爲什麼返回的指針地址的十六進制值總是按遞減順序? 例如這裏int aint 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

+2

重要嗎? –

+0

地址未分配給變量,但值存儲在內存地址中。 – moooeeeep

+0

@moooeeeep我的意思是一樣的,只是沒有使用正確的話。:) –

回答

4

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語言規範的角度來看,未指定後續分配變量的內存位置順序。因此,這取決於...

3

你不能讓這個任何假設。隨着一些編譯器,一些架構和一些編譯器開關,你可以看到部份的行爲,即局部變量依次降低堆棧地址被分配,但優化等因素,可以改變這種行爲。

+1

額外的挑剔:** C中沒有堆棧**大多數*實現*使用堆棧。 *在理論上*,實現甚至可以使用一些巧妙的地址隨機化技術來分配自動變量。或者它可以選擇重新排列變量以最小化對齊需求。或者它可以使用浮動和整數分開的位置。任何事情... – wildplasser

+1

@wildplasser:或者它可以只是優化了一些變量(當然,只有當你不接受他們的地址) – ninjalj

0

很多ABI定義了一個向下增長的堆棧。

2

您正在比較的地址的變量都是在堆棧上分配的局部變量。現在堆棧增長的方式(向上或向下)取決於架構。看起來就像你的情況一樣,堆棧正在向下擴展,所以你看到的地址在減少。

More on this here

0

總髮和半準確的解釋(不考慮關於與棧和堆差異的詳細信息)是:你希望儘量減少在內存中的靜態分配的東西,你需要動態分配的東西碰撞。當您的程序運行時,動態內容通常會增大。爲了最大化分配動態內容的能力,靜態內容和動態內容通常分配在內存空間的相對兩端,動態內容會增加到靜態內容。在你的具體情況下,它看起來像你的編譯器將內存中的靜態內容加載得很少,並且從內存的開始到內存的開始(靜態內容的方向)增加動態內容。