[英]How does c compiler allocate memory for structures?
通過研究結構,我想到了一個問題,即編譯器如何將結構存儲在內存中,這意味着
struct
{
int number;
char name[nam];
}h;
我想知道的是成員(這里是number
和name
)的存儲方式(例如,如果將數字存儲在地址2000中並將name
存儲在2990中,則它們是按順序存儲還是存儲在隨機位置)?
內存按順序分配給結構成員:
+------------+------------------+-----+-----+-----+-----+-----+-----+
| | ........ | | | | | | |
| | | | | | | | |
+------------+--------+---------+-----+-----+-----+-----+-----+-----+
+ + | name[0] name[nam-1]
+------+-----+ | +------------------+----------------+
| | |
| | |
v v v
number padding name[nam]
但是,與數組不同,為一個結構分配的內存可能會打包,也可能不會打包,即,在任何成員的分配空間之后可能會有一些填充(但是在第一個成員之前不允許填充)。
您可以在數據結構對齊中找到答案:
數據結構對齊是在計算機內存中排列和訪問數據的方式。 它由兩個獨立但相關的問題組成:數據對齊和數據結構填充。 當現代計算機讀取或寫入內存地址時,它將以字大小的塊(例如,在32位系統上為4字節的塊)進行讀取。 數據對齊意味着將數據放置在等於字長的倍數的內存偏移處,這由於CPU處理內存的方式而提高了系統的性能。 為了對齊數據,可能有必要在最后一個數據結構的末尾與下一個數據結構的末尾(即數據結構填充)之間插入一些無意義的字節。
字段將始終按寫入順序排列,但它們之間可能會有填充。
我在第一年的演講中復制了這張圖片。 希望對您有所幫助(應該):
根據C99 6.7.2.1/13的結構和聯合說明符
在結構對象中,非位字段成員和位字段所在的單元的地址按照聲明的順序增加。 指向經過適當轉換的結構對象的指針指向其初始成員(或者,如果該成員是位字段,則指向它所駐留的單元),反之亦然。 結構對象內可能存在未命名的填充,但在其開始處沒有。
因此,在您的示例中,字段name
必須緊隨字段number
之后,但是在兩個字段之間可能會添加填充。 name
字段后也可能有填充,用於確保這些結構的數組將每個元素適當對齊。
數組可以兩種不同的方式存儲。 在您的結構中,如果它的大小是恆定的,例如char array[42]
或者如果它們在編譯時大小未知,則使用malloc
進行分配,並在您的結構中具有指向該數組的指針。
在第一種情況下,一個內存塊將包含您的所有結構數據,包括完整的陣列。
在第二種情況下,您會在內存中的結構元素地址處找到一個指針,該指針包含內存中數組的實際地址,因此您只會看到一個數字(指針的指向地址)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.