簡體   English   中英

32位和64位架構上的c中的結構填充之間有何區別?

[英]what is difference between structure padding in c on 32bit and 64bit architecture?

我從http://fresh2refresh.com/c-programming/c-structure-padding/讀取了內存,以32位處理器中的4個字節和64位處理器中的8個字節為一組,但沒有弄清楚之間的區別這兩個。

struct structure2 
    {
           int id1;
           char name;
           int id2;
           char c;
           float percentage;                      
    };

通過32位處理器(更具體地說,它是在談論數據總線的大小而不是寄存器的大小),這意味着一次將讀取和處理32位(4字節)的數據。

現在,考慮一個int:

int a=10; //assuming 4 bytes

00000000 000000000 00000000 00001010

假設沒有端序架構,則將其存儲為:

------------------------------------------------------------------------
| 00001010  |  00000000  |  00000000   |  00000000   |  <something_else>   
-------------------------------------------------------------------------
  1st byte     2nd byte     3rd byte      4th byte
\--------------------------------------------------/
                         |
               4 bytes processed together

在這種情況下,當處理器將讀取要處理的數據時,它可以一次性處理整個整數(所有4個字節在一起)(更嚴格地說,在1個機器周期內)

但是,請考慮以下情況:存儲了相同的整數,

------------------------------------------------------------------------
|<something_else>| 00001010  |  00000000  |  00000000   |  00000000   |     
-------------------------------------------------------------------------
  1st byte     2nd byte     3rd byte      4th byte
\------------------------------------------------------/
                         |
               4 bytes processed together

在這種情況下,處理器將需要2個機器周期來讀取整數。


大多數體系結構始終嘗試最小化CPU周期。 因此,內存中的第一種排列被許多編譯器所青睞,因此會強制執行對齊要求(填充)。 因此,將4個字節的int存儲在以4s的倍數開頭的地址中,將chars存儲為1s的倍數,將8個字節的doubles存儲為8s的倍數,將8個字節long long int存儲為8s的倍數,依此類推...

現在考慮你的結構

struct structure2 
{
       int id1;   //assuming 4 byte int
       char name;  // 1byte
       int id2;    //4 byte
       char c;     // 1 byte
       float percentage;    //assuming 4 byte float                  
};

id1將存儲在內存中的某個地址(以4的倍數開頭)中,並占用4個字節。

名稱將占用下一個字節。

現在,如果將id2存儲在下一個字節中,則會破壞上面的對齊規則。 因此,它將保留3字節的填充並以adress開始存儲,該地址是4的下一個倍數,將占用4字節。

對於c來說 ,同樣的事情與name相同。 它占用下一個1字節,並保留3字節的填充。

最后百分比存儲在接下來的4個字節中。

因此,結構的總大小變為20個字節


可以說一個更復雜的情況

struct mystructure
{
   char        a; //1 byte char
   double      b; // 8 byte double
   int         c; // 4 byte int
}

乍一看,這里的大小可能是20字節 (char為1字節+ 7字節為填充+ 8字節為double + 4字節為int)。

但是實際大小為24個字節

假設有人聲明了此結構的數組

struct mystructre arr[4];

盡管arr [0]正確對齊,但此處(假定為20字節結構),但是如果仔細檢查,會發現arr [1] .b未對齊。 因此,在結構的末尾添加4個字節的額外填充以使結構大小為其對齊方式的倍數。(每個結構也都有其自己的對齊要求)。

因此,總大小為24個字節。


整數,長整數等的大小由編譯器決定。 編譯器通常會處理處理器體系結構,但可能會選擇不這樣做。

同樣,是否使用填充由編譯器決定。 不填充稱為打包 一些編譯器具有允許打包的顯式選項。

在GCC(GNU C編譯器)中,您可以使用__attribute__((__packed__))做到這一點,因此在以下代碼中

struct __attribute__((__packed__)) mystructure2 
{
 char a;
 int b;
 char c;
};

由於明確請求打包結構, mystructure2的大小為6個字節。 此結構將較慢處理


您現在可以自己弄清楚,在64位處理器中會發生什么,或者int的大小是否不同。

該網站並沒有精確地確定使用哪種64位平台,但是似乎假定使用長度對齊的整數的ILP64( intlong和指針為64位)平台。 這意味着int在32位處理器上為4個字節,在64位處理器上為8個字節,並且每個字節必須以其自身長度的倍數對齊。

結果是nameid2之間的填充長度發生了變化(保留id2的對齊所必需的填充)。

在32位平台上,將有3個字節的填充。 在64位平台上,將有七個。

cpercentage之間的填充很可能不會更改,因為浮點變量的大小不受處理器位的影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM