前些時候將Structure內的資料以raw data的方式在處理時,才發現到原來Structure內的element並不是緊密相連在一起的。如以下例子:
typedef struct{
char str01[5];
long long01;
char str02[5];
char str03[5];
}TESTSTRUCT;
printf("Offset of long01:[%d]\n", ((char*)&tTest.long01)-((char*)&tTest));
printf("Offset of str02:[%d]\n", tTest.str02 - ((char*)&tTest));
printf("Offset of str03:[%d]\n", tTest.str03 - ((char*)&tTest));
printf("Sizeof TESTSTRUCT:[%d]\n", sizeof(tTest));
以VC在WinXP 32Bit的執行結果是:
Offset of long01:[8]
Offset of str02:[12]
Offset of str03:[17]
Sizeof TESTSTRUCT:[24]
可以看到long01在Structure內的Offset是8,而不是預期的5。這就是Data structure alignment的影響。可參考這裏的解釋。其主要就是為了程式Performance的關係。
同樣的,Structure的size變為24。也是Data structure alignment的影響。
在C/C++中要強迫Compiler使用多少padding數,可以用#pragma pack(n)這個語法來控制。
寫了十多年的C,最近才發現有這個問題。 XD
介紹一下~Han是我跟大師(Nelson)大學/研究所的同窗兼室友。
回覆刪除沒錯~這個問題也是我在寫AVFarSight(一個號稱跨平台區網視訊串流的物件函式庫)才發現。當初是用structure在傳輸資料,才發現每個平台/compiler預設的padding設定不一樣,導致再比對長度時發生錯誤。解決方法也是用#pragma pack(n)明確指定。
回覆刪除Hello Han ~
回覆刪除學習
作者已經移除這則留言。
回覆刪除typedef struct{
回覆刪除char str01[5];
char str02[5];
char str03[5];
char str04[5];
char str05[5];
char str06[5];
} test_struct2;
為什麼跑出來是 30 ?
ps. 我用< pre >他不給我用...
這是因為char的data padding值就是1,因為你的structure中的data type都是char,所以宣告多少就是多少。
回覆刪除你可參考Wiki連結中的Typical alignment of C structs on x86章節的解釋。不同data type在不同os或Compiler裏,其padding值是不同的。
#pragma pack(push) /* push current alignment to stack */
回覆刪除#pragma pack(1) /* set alignment to 1 byte boundary */
typedef struct _test
{
char ch0;
char ch1;
}test;
#pragma pack(pop) /* restore original alignment from stack */
請問為何 兩個 char 卻佔用 4 BYTES ?
To 匿名
回覆刪除請問在你的實驗中如果把ch1拿掉
sizeof(test); 有變小嗎? 還是仍舊是4?
TO Abow,
回覆刪除我的環境是 arm linux 環境,
發現結構內的成員都不變的話,用 typedef struct 跟 struct 宣告出來的結果是不一樣的...
環境:arm LINUX C++
struct REGS_A
{
char lo ;
char hi ;
char hi2 ;
}__attribute__ ((packed ));
typedef struct
{
char lo ;
char hi ;
char hi2 ;
}REGS_B __attribute__ ((packed ));
計算結構的大小
printf("REGS_A size : %d\n" , sizeof( struct REGS_A ) ); ---> 3
printf("REGS_B size : %d\n" , sizeof( REGS_B ) ); ---> 4
typedef struct 宣告的結構大小都會是回傳 4 的倍數
PS: 其實不知道 typedef struct 是否可以搭配 __attribute__ ((packed )); ,但是編譯過程沒有出現任何訊息。 但是 packed 卻沒有發揮效果...
我在Mac OS X (gcc)實驗的結果都是 3
回覆刪除