2013-12-19 29 views
4

通過研究結構導致我的一個問題是如何結構由編譯器存儲在存儲器中,這意味着考慮c編譯器如何爲結構分配內存?

struct 
{ 
     int number; 
     char name[nam]; 
}h; 

我想知道是怎麼成員(這裏是numbername)存儲(例如,如果號碼存儲在地址2000中,並且name存儲在2990中,那麼它們是按順序存儲還是存儲在隨機地址中)?

+3

該代碼不能編譯。你是不是指'char nam [];'? – delnan

+0

嗯,嚴格來說,結構的空間是由加載程序和虛擬內存管理器在運行應用程序時分配的。 –

回答

4

內存在的順序分配用於結構構件:

+------------+------------------+-----+-----+-----+-----+-----+-----+ 
|   |  ........  |  |  |  |  |  |  | 
|   |     |  |  |  |  |  |  | 
+------------+--------+---------+-----+-----+-----+-----+-----+-----+ 
+   +  |  name[0]        name[nam-1] 
+------+-----+  |   +------------------+----------------+ 
     |    |       | 
     |    |       | 
     v    v       v 
    number   padding      name[nam] 

但是,不同於陣列,用於一結構所分配的存儲器可以是或可以不是緊縮的,即,可以存在所分配的空間後一些填充的任何成員(但在第一個成員之前不允許填充)。

+2

你確定你被允許複製和發佈圖形。 @haccks – alk

+0

@alk;我添加了參考。 – haccks

+1

我知道有人曾經爲此付出了很多錢。 @haccks – alk

2

您可以在Data structure alignment找到了答案:

數據結構對齊數據配置,在 計算機內存訪問的方式。 它由兩個獨立但相關的問題組成:數據 對齊和數據結構填充。當現代計算機從存儲器地址讀取 或寫入存儲器地址時,它將以字大小爲 塊(例如,在32位系統上的4字節塊)執行此操作。數據對齊意味着 將數據置於等於字 大小的幾倍的存儲器偏移處,這由於CPU 處理存儲器的方式而增加了系統的性能。要對齊數據,可能需要在最後一個數據結構的末尾和下一個數據結構填充的下一個開始之間插入一些無意義的字節。

2

字段將始終按寫入的順序排列,但它們之間可能會有填充。

-1

數組可以以兩種不同的方式存儲。在你的結構中,如果它的大小是不變的,比如char array[42],或者如果它們在編譯時有一個未知的大小,可以使用malloc進行分配,並且在你的結構中有一個指向數組的指針。

在第一種情況下,一塊內存將包含您的所有結構數據,包括完整數組。

在第二種情況下,您會在內存中找到結構元素地址處的一個指針,該指針包含內存中數組的實際地址,因此您只能看到一個數字(指針的指針地址)

2

我從第一年的演講中複製了這張圖片。我希望它有助於(應該):

enter image description here

+2

嗯...挑選尼克,'sizeof(結構)> =Σsizeof(成員)'。 –

+0

什麼是摘n? :/ – Maroun

+1

'挑選'是另一種寫作'挑剔'的方式,最初是指從某人的頭皮上找到'蝨子'或'蝨卵'或'蝨子幼蟲'的過程,這是一個尋找微小物體的艱難過程需要刪除。如今,它指的是尋找小故障。蘋果字典表示,挑剔是「尋找小的或不重要的錯誤或錯誤,尤其是。爲了批評不必要'和'挑剔的錯誤發現'。 –

2

從C99 6.7.2.1/13結構和聯合說明

內的結構物,非位字段成員單位在 哪些位字段駐留的地址在 中的地址增加,它們被聲明。指向結構對象的指針(適當地爲 轉換)指向其初始成員(或者如果該成員是位域,則返回其所在的單位),反之亦然。 結構對象中可能存在未命名的填充,但不包括其起始處的 。

等等領域name必須遵循領域number在你的榜樣,但也有可能是這兩個領域之間添加填充。在name字段後面也可能會有填充,用於確保這些結構的數組將使每個元素都適當對齊。