[英]What Is the difference between how the char datatype is stored or represented in 32bit vs 64bit in 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( int
, long
和指針為64位)平台。 這意味着int
在32位處理器上為4個字節,在64位處理器上為8個字節,並且每個字節必須以其自身長度的倍數對齊。
結果是name
和id2
之間的填充長度發生了變化(保留id2
的對齊所必需的填充)。
在32位平台上,將有3個字節的填充。 在64位平台上,將有七個。
c
和percentage
之間的填充很可能不會更改,因為浮點變量的大小不受處理器位的影響。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.