看板 C_and_CPP 關於我們 聯絡資訊
大家好: 我想問關於struct的問題 最近無聊發現一個問題,後來有上網查還是一知半解 請版上先進不吝指教 如下 struct a{ char x; int y; short z; }; 結果去印sizeof(struct a)是12 而 struct b{ char x; short y; int z; }; 印出sizeof(struct b)是8 第一個我可以了解 0: x p p p 4: y y y y 8: z z p p 但是就第二個來講 我以為也會是12 但是卻是8 0: x p p p 4: y y p p 8: z z z z 但是卻好像不是這樣? 難道是? 0: x p y y 4: z z z z 這樣就很怪了阿 網路上查說這叫做對齊 主要目的是 "抓資料時可以一次抓" 網路上舉例 若一個int從位置6開始放 放在 6 7 8 9 非似的倍數就要抓兩次 可是,如果是這樣那應該都會對齊四吧? 為什麼第二種方式會對齊 2呢? 假設機器是32bit的話,怎麼想也是對齊4吧? struct x{ char a; char b; short c; } 這卻會是 0: a b c c 為啥不是 0: a x x x 4: b x x x 8: c c x x 這樣呢? 感謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.136.182.93
Feis:因為是對齊阿. 不要有人跨過邊界就可以了. 10/16 21:43
azureblaze:每種資料型態的對齊不同 10/16 21:45
azureblaze:x86一般char隨便放,short對齊2 int對齊4 10/16 21:46
azureblaze:c++11有alignof(TYPE)可以看到底是多少 10/16 21:47
kumusou:為什麼不是對齊4阿 ? 10/16 21:54
Feis:假設對齊 4 最快, 還要考慮空間浪費的問題. 10/16 22:07
purincess:alignment對C語言來說不是implementation-defined的嗎@@ 10/16 22:25
kumusou:跪求解析 >"< 10/16 22:27
kumusou:其實我比較想知道對齊2、4的理念是甚麼 10/16 22:36
kumusou:為什麼編譯氣會這樣翻? @@ 10/16 22:37
Feis:強迫對齊 4 你 x 會很多阿. 每個 char 只實際使用到 1/4 空間 10/16 22:42
Feis:同理 short 本身如果只佔 2, 那對齊 4 只使用到 1/2 空間 10/16 22:43
handsome616:好複雜... 10/16 22:45
kumusou:那完全不對齊呢? 不是更省空間嗎 @@ 10/16 22:45
Feis:是阿. 但是假設對齊 4 效率最高的話, 效率就被犧牲了 10/16 22:46
kumusou:再根據資料型態 直接讀出對應的BYTE樹好像比較好@@ 10/16 22:47
Feis:這是個 trade-off, 所以是實作相依 10/16 22:47
那如果都不對齊的話 如 char a; short b; int c; a b b c c c c 再根據定義好的資料型態所對應的byte數 去讀資料,似乎又省空間又快? ※ 編輯: kumusou 來自: 220.136.182.93 (10/16 22:49)
Feis:如果今天我們 short 是對齊 3, 那有些 short 會跨過 4 的邊界 10/16 22:48
Feis:你 '可能' 要讀兩次才能讀到一個 short 10/16 22:48
Feis:此外讀進 4 個 bytes 要取出其中任意個 bytes 要花時間 10/16 22:49
Feis:以上都假設我們一次讀 4 個 bytes, 然後對齊 4 最快的情況 10/16 22:50
Feis:你的例子我們要讀 c 的時候, 要讀兩次|a b b c| c c c x| 10/16 22:50
Feis:然後還要把其中一個跟另外三個重新組起來 要解開重組 10/16 22:51
Feis:假設硬體不支援的話就會很沒效率 10/16 22:51
為啥要你要把他四個一組阿? 假設 a b b c c c c 0 1 2 3 4 5 6 他可以直接在位置3直接抓sizeof(int)出來就是c了不是嗎? ※ 編輯: kumusou 來自: 220.136.182.93 (10/16 22:53)
Feis:所以你為什麼說 32-bit 要對齊 4 ? 10/16 22:55
其實我是想 如果| a b b c | c c c p | c要讀兩次,所以要對齊四 i.e. | a p p p | b b p p | c c c c | 都抓一次就好 但是如果對齊二的話 i.e. | a p b b | c c c c | c讀一次 但他怎麼讀b啊? 我問題點比較像是這邊? (也是讀一次嗎?) ※ 編輯: kumusou 來自: 220.136.182.93 (10/16 22:59)
Feis:那你的問題是我們為什麼需要對齊嗎 XD 10/16 22:56
Feis:他就把 | a p b b | 抓過來然後拿後面兩個 bytes 就好~ 10/16 23:00
kumusou:他怎麼知道b是後面兩個byte啊? 10/16 23:01
tomnelson:其實你可以嘗試把你提出來有不同sizeof值的struct,寫一 10/16 23:02
Feis:kumusou: 那他怎麼知道 c 是後面那一組阿. 這是一樣的問題 10/16 23:02
tomnelson:段小程式,然後看compiler產生的assembly是怎麼樣存取其 10/16 23:03
那我說一下我現在的理解喔 因為讀資料幾乎都是以記憶體4的倍數在讀 | a p b b | c c c c | 0 1 2 3 4 5 6 7 所以就算知道b的記憶體位置是從2開始 他一次還是會先讀到0起始的4bytes 在解析出b 這樣對嗎? ※ 編輯: kumusou 來自: 220.136.182.93 (10/16 23:06)
tomnelson:中struct裡的field(member)的,就可以知道apbb的b怎麼樣 10/16 23:04
tomnelson:被讀出來的. 10/16 23:04
tomnelson:其實你的問題也牽涉到計算機硬體呀!不然不用對齊不是更 10/16 23:05
tomnelson:省空間嗎?所以建議要想一下(或問一下)為什麼會這樣... 10/16 23:06
tomnelson:"記憶體4的倍數在讀"->這是因硬體而如此的! 10/16 23:07