2014-04-29 34 views
2

數組的名稱如何存儲在內存中?數組本身的名稱,它存儲在哪裏

例如,如果我寫:

char arr[10]; 

項目存儲在存儲器從虛擬地址&arr[0]這實際上是ARR,的價值,但其中是arr自身存儲從數組?

也是如此靜態多維數組的行:

char arr[10][20]; 

ARR本身,而且還常用3 [0],編曲[1] .... ARR [9]是所有無地址自己。

那麼名稱存儲在哪裏?

+3

編譯後名稱本身會丟失我猜測只有帶反射的語言或解釋的語言才需要存儲名稱 –

回答

5

如果您的意思是文字名稱您聲明它,通常編譯出來,除非您編譯調試符號-g

如果你在堆棧中聲明瞭某些東西,那麼機器碼通常將數組元素指向幀指針$ebp的偏移量。

要回答您的暗示問題,對於堆棧中的數組,它不存在。機器代碼不知道什麼是arr。它只知道你使用偏移量(你的代碼中的索引)尋址的是一個內存區域。

這個問題對於堆上的數組更有意義,因爲現在你有一個指針(它有自己的地址)以及存放實際數組的內存(它在堆上,並存儲在指針內) )。

請考慮以下代碼。

char* arr = malloc(5); 

假設你使用調試符號編譯,如果你看一下里面&arrgdb,你會看到在指針arr存儲地址。

如果您爲堆棧上的數組創建單獨的指針,則可以演示相同的事情。

char arr[10]; 
char* ptr = arr; 

在這裏,你將看到ptr具有單獨的存儲(p &ptr),並保持的arr作爲它的值的地址,但&arr本身等於其第一元素的地址。

+0

謝謝。我知道關於動態分配的數組。我的問題是與靜態的問題,你很好地回答。謝謝。 – pHbits

+0

@ user2737130,你的隱含問題比你在問它的時候可能實現的稍微微妙一些,因爲它存在於C中數組和指針之間的核心區別之一 – merlin2011

+0

@ user2737130,如果這個答案解決了你的問題,請標記它作爲接受的答案。 – merlin2011

3

編譯它時,數組的名稱會丟失。它僅供參考。元素存儲在堆棧中,但編譯後數組名稱將會丟失,除非在調試中沒有-g選項。

3

arr本身,而且arr [0],arr [1] .... arr [9]都沒有地址本身。

arr只是數組的基地址。通過向該地址添加偏移來定位各個元素。編譯代碼後,數組的名稱沒有用,除了調試。

+0

奇怪的是,甚至整個arr [0] .. arr [9]終於從機器代碼本身中被省略了。但我想這是合乎邏輯的 – pHbits

3

正如其他人所說,您的變量的名稱是符號在您的源代碼。它們沒有被編譯器翻譯成機器代碼,因此無法找到,雖然它們可以使用適當的選項附加到您的可執行文件(例如,gcc中的-g,它將生成操作系統本機格式的調試信息)用於調試目的。

在機器代碼,變量由存儲單元,其可以是各種各樣的,根據本機的編譯上和引用: 功能參數和局部變量將取決於calling conventions和優化,並且通常(在x86)從特殊寄存器%ebp(稱爲基址指針)計算出的地址和偏移量。它們也可以作爲寄存器直接傳遞(例如,第一個參數可以轉換爲通用寄存器),或者作爲內存中另一個特殊地址(特定於該函數)的偏移量。 當取消引用指針時,變量的地址是從內存間接獲取的(並且可能僅在運行時纔可用,如使用動態內存分配(如malloc))。底線,在機器代碼中,通常不會找到變量名稱(從C編譯時)。相反,你有寄存器和地址(或者,確切地說,數字常量和你必須猜到的計算值是地址),這就是爲什麼只通過查看二進制來理解代碼的原始含義是一個難題的部分原因(儘管試圖將二進制代碼反彙編爲彙編代碼所帶來的問題)。