2014-02-25 31 views
0

變量如何在內存中找到?我有這樣的代碼c變量在內存中的分配,指針

int w=1; 
int x=1; 
int y=1; 
int z=1; 

int main(int argc, char** argv) { 
    printf("\n w %d",&w); 
    printf("\n x %d",&x); 
    printf("\n y %d",&y); 
    printf("\n z %d",&z); 
    return (EXIT_SUCCESS); 
} 

,並打印此

w 134520852 
x 134520856 
y 134520860 
z 134520864 

我們可以看到,其他時候整數聲明和分配,地址是移動四個位置(字節,我想,它似乎很邏輯) 。但是,如果我們不給變量賦值,例如下面的代碼:

int w; 
int x; 
int y; 
int z; 

int main(int argc, char** argv) { 
    printf("\n w %d",&w); 
    printf("\n x %d",&x); 
    printf("\n y %d",&y); 
    printf("\n z %d",&z); 
    return (EXIT_SUCCESS); 
} 

它打印此

w 134520868 
x 134520864 
y 134520872 
z 134520860 

我們可以看到有地址之間的四個位置,但他們不是爲了。爲什麼是這樣?在這種情況下,編譯器如何工作?

如果你想知道我爲什麼問這個,是因爲我開始學習一些安全,我想了解一些攻擊,例如,如何溢出攻擊整數工作,我我一直玩C指針來修改其他變量,通過添加更多的位置比變量的大小和類似的東西。

+1

使用%p作爲地址。第二個例子中的變量將自動分配0值。 –

+3

在搜索框中尋找'bss'。區別在於數據段中的初始化數據和BSS中的未初始化數據(由符號開始的塊),該段保存零初始化數據。例如[爲什麼需要BSS段?](http://stackoverflow.com/questions/9535250/why-is-the-bss-segment-required) –

+0

編譯器會在所選的任何位置分配變量。 –

回答

2

你的第一範例初始化變量,其產生不同的分配的代碼。通過查看由gcc(gas)生成的彙編文件,我得到:

.globl _w 
    .data 
    .align 4 
_w: 
    .long 1 
    .globl _x 
    .align 4 
_x: 
    .long 1 
    .globl _y 
    .align 4 
_y: 
    .long 1 
    .globl _z 
    .align 4 
_z: 
    .long 1 

而這基本上決定了內存地址。

你的第二個例子創建未初始化的變量,並作爲喬納森說,這些進入BSS。彙編代碼是:

.comm _w, 4, 2 
.comm _x, 4, 2 
.comm _y, 4, 2 
.comm _z, 4, 2 

而這意味着你不能保證這些變量在內存中的位置順序。

1

第二組數字也是連續的,只是沒有下令一樣的來源。我認爲這樣做的原因很簡單,當初始化變量時,編譯器將它們按順序排列,因爲它維護初始化的順序,在第二種情況下,您只是得到一個隨機順序。

在這種依賴於編譯器的情況;在這兩種情況下,我都得到了相同的模式(相隔4個字節)。