Ⅰ IAR定義的結構體變數,是自動對齊么,怎麼才能對齊
具體要查手冊。
一般說來,應該是默認自動對齊的,可以通過預處理指令開關這個選項
其它編譯器,一般是:
#pragma
pack(NNN)
NNN是1、2或者4、8、16
具體要查手冊
Ⅱ 結構體成員的位元組對齊
這個問題都很有深度啊;
首先我要說的是,位元組對齊在不同編譯器下語法是不一樣的,在GCC中是#pragma push(1) #pragma pack(); 在MS C++中用VC的代碼項里可以調整,默認是8位元組;
typedef struct
{
char c;
int i;
}test;
位元組對齊,是對齊,比如說char 與 int 如果是4位元組對齊,那麼char也會佔用4個位元組,總共佔8位元組,而且結構體對象存儲是按照順序存的,char 肯定在int前面。第二種情況如果1位元組對齊,意味著char只佔1位元組,而結下來int會佔用4位元組,這個N位元組對齊的意思是,每個成員佔用空間必須是N位元組的倍數,不足N位元組的佔用N位元組。那麼以1位元組對齊那它佔用5個位元組。
還有你說的每種數據是低位還是高位在前,這個根處理器有關,Intel處理是小端對齊,比如說一個整數522387969用16進製表示是:0x1f 23 02 01,在Intel處理器中表示是0x01 02 23 1f,所以在內存用0x01 02 03 1f來示522387969,這就是所謂有小端對齊;但在arm處理器中522387969表示是0x1f 23 02 01,這就是所謂的大端對齊,這種方式又叫作網路位元組序。
當然前面說的位元組序只是對int long short這些內置(built in)數據類型用效,對結構體內如果有int long這類成員也會有所謂的位元組序,如前面所說,不管是什麼序結構體對象存儲是按照順序存,先定義的成員肯定在後定義的成員前面,但單個成員有位元組序,不知這樣說,你的明白?
不是,請仔細體會這句話:這個N位元組對齊的意思是,每個成員佔用空間必須是N位元組的倍數,不足N位元組的佔用N位元組。
大於N位元組就湊夠N位元組的倍數,比如按3位元組對齊,那麼一個4位元組的int將占據6位元組~
Ⅲ VC6.0編譯器里,C語言結構體怎麼對齊位元組對齊問題怎麼解決我想給結構體成員連續賦值,但是結構
具體什麼問題?貼段代碼看看
Ⅳ 在arm中c語言編程,定義的多位元組變數和結構體,最好使其為對齊存放."對齊存放"是
ARM支持16bit和32bit的地址訪問,即變數地址能夠被2或4整除,這時性能比較好,也便於移植。結構體的對齊就是指的結構體內部的每個成員變數地址盡可能對齊到2或4位元組位置,如定義為:
struct{
char ch1;
char ch2;
short ss;
int i;
}var;
字元變數ch1, ch2為位元組對齊,短整型變數ss為半字對齊,整型變數i為字對齊,結構體內的變數比較緊湊,且已自然對齊,結構體變數var佔用總空間為8個位元組。如果改為這樣:
struct{
char ch1;
short ss;
char ch2;
short ss;
int i;
}var;
var變數最終佔用的空間為12個位元組,存取這個結構體時比前面那個需要的時間要多,另外如果用pack(1)指定結構體位元組對齊的話,後面的方式移植到其它系統可能會出現死機問題。
Ⅳ C語言結構體長度位元組對齊問題
因為當結構體中有多個數據類型時,結構體的長度對齊是按數據類型長度最長的那個來對齊的,double類型佔8個位元組,所以每個成員變數都按8個位元組的長度來算,就是5*8=40,驗證程序如下:
#include<stdio.h>
structchji
{
charname[9];
intnumber;
charsex;
doublescore;
floataa;
};
structchjistu;
intmain()
{
printf("sizeof(structchji)=%d ",sizeof(structchji));
return0;
}
運行結果:sizeof(struct chji)=40
如果要按單個位元組的長度來對齊的話,代碼如下:
#include<stdio.h>
#pragmapack(1)
structchji
{
charname[9];//9
intnumber;//4
charsex;//1
doublescore;//8
floataa;//4
};
structchjistu;
#pragmapack()
intmain()
{
printf("sizeof(structchji)=%d ",sizeof(structchji));
return0;
}
運行結果:sizeof(struct chji)=26
即9+4+1+8+4=26,你可以查下#pragma pack()相關的資料的,就會清楚了。
Ⅵ 下載程序時位元組對齊
一、快速理解
1、內存對齊原則:
第一個成員的首地址為0.
每個成員的首地址是自身大小的整數倍
結構體的總大小,為其成員中所含最大類型的整數倍。
2、什麼是位元組對齊?
在C語言中,結構是一種復合數據類型,其構成元素既可以是基本數據類型(如int、long、float等)的變數,也可以是一些復合數據類型(如數組、結構、聯合等)的數據單元。在結構中,編譯器為結構的每個成員按其自然邊界(alignment)分配空間。各個成員按照它們被聲明的順序在內存中順序存儲,第一個成員的地址和整個結構的地址相同。
為了使CPU能夠對變數進行快速的訪問,變數的起始地址應該具有某些特性,即所謂的」對齊」.
比如4位元組的int型,其起始地址應該位於4位元組的邊界上,即起始地址能夠被4整除.
3、 位元組對齊有什麼作用?
位元組對齊的作用不僅是便於cpu快速訪問。
同時合理的利用位元組對齊可以有效地節省存儲空間。
對於32位機來說,4位元組對齊能夠使cpu訪問速度提高,比如說一個long類型的變數,如果跨越了4位元組邊界存儲,那麼cpu要讀取兩次,這樣效率就低了。
但是在32位機中使用1位元組或者2位元組對齊,反而會使變數訪問速度降低。所以這要考慮處理器類型,另外還得考慮編譯器的類型。在vc中默認是4位元組對齊的,GNU gcc 是默認4位元組對齊。
4、 更改C編譯器的預設位元組對齊方式
在預設情況下,C編譯器為每一個變數或是數據單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變預設的對界條件:
使用偽指令#pragma pack (n),C編譯器將按照n個位元組對齊。
使用偽指令#pragma pack(),取消自定義位元組對齊方式。
另外,還有如下的一種方式:
__attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。 ·
attribute ((packed)),取消結構在編譯過程中的優化對齊,按照實際佔用位元組數進行對齊。
5、 舉例說明
例1
struct test
{
char x1;
short x2;
float x3;
char x4;
};
1
2
3
4
5
6
7
1
2
3
4
5
6
7
由於編譯器默認情況下會對這個struct作自然邊界(有人說「自然對界」我覺得邊界更順口)對齊,結構的第一個成員x1,其偏移地址為0,占據了第1個位元組。第二個成員x2為short類型,其起始地址必須2位元組對界。
因此,編譯器在x2和x1之間填充了一個空位元組。結構的第三個成員x3和第四個成員x4恰好落在其自然邊界地址上,在它們前面不需要額外的填充位元組。
在test結構中,成員x3要求4位元組對界,是該結構所有成員中要求的最大邊界單元,因而test結構的自然對界條件為4位元組,編譯器在成員x4後面填充了3個空位元組。整個結構所佔據空間為12位元組。
例2
#pragma pack(1) //讓編譯器對這個結構作1位元組對齊
struct test
{
char x1;
short x2;
float x3;
char x4;
};
#pragma pack() //取消1位元組對齊,恢復為默認4位元組對齊
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
這時候sizeof(struct test)的值為8。
例3
#define GNUC_PACKED __attribute__((packed))
struct PACKED test
{
char x1;
short x2;
float x3;
char x4;
}GNUC_PACKED;
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
這時候sizeof(struct test)的值仍為8。
二、深入理解
①什麼是位元組對齊,為什麼要對齊?
現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變數的訪問可以從任何地址開始。
但實際情況是在訪問特定類型變數的時候經常在特定的內存地址訪問,這就需要各種類型數據按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
對齊的作用和原因:各個硬體平台對存儲空間的處理上有很大的不同。一些平台對某些特定類型的數據只能從某些特定地址開始存取。比如有些架構的CPU在訪問一個沒有進行對齊的變數的時候會發生錯誤,那麼在這種架構下編程必須保證位元組對齊.其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對數據存放進行對齊,會在存取效率上帶來損失。比如有些平台每次讀都是從偶地址開始,如果一個int型(假設為32位系統)如果存放在偶地址開始的地方,那麼一個讀周期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀周期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit數據。顯然在讀取效率上下降很多。
②位元組對齊對程序的影響:
先讓我們看幾個例子吧(32bit,x86環境,gcc編譯器):
設結構體如下定義:
struct A
{
int a;
char b;
short c;
};
struct B
{
char b;
int a;
short c;
};
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
現在已知32位機器上各種數據類型的長度如下:
char:1(有符號無符號同)
short:2(有符號無符號同)
int:4(有符號無符號同)
long:4(有符號無符號同)
float:4 double:8
那麼上面兩個結構大小如何呢?
結果是:
sizeof(strcut A)值為8
sizeof(struct B)的值卻是12一、快速理解
1、內存對齊原則:
第一個成員的首地址為0.
每個成員的首地址是自身大小的整數倍
結構體的總大小,為其成員中所含最大類型的整數倍。
2、什麼是位元組對齊?
在C語言中,結構是一種復合數據類型,其構成元素既可以是基本數據類型(如int、long、float等)的變數,也可以是一些復合數據類型(如數組、結構、聯合等)的數據單元。在結構中,編譯器為結構的每個成員按其自然邊界(alignment)分配空間。各個成員按照它們被聲明的順序在內存中順序存儲,第一個成員的地址和整個結構的地址相同。
為了使CPU能夠對變數進行快速的訪問,變數的起始地址應該具有某些特性,即所謂的」對齊」.
比如4位元組的int型,其起始地址應該位於4位元組的邊界上,即起始地址能夠被4整除.
3、 位元組對齊有什麼作用?
位元組對齊的作用不僅是便於cpu快速訪問。
同時合理的利用位元組對齊可以有效地節省存儲空間。
對於32位機來說,4位元組對齊能夠使cpu訪問速度提高,比如說一個long類型的變數,如果跨越了4位元組邊界存儲,那麼cpu要讀取兩次,這樣效率就低了。
但是在32位機中使用1位元組或者2位元組對齊,反而會使變數訪問速度降低。所以這要考慮處理器類型,另外還得考慮編譯器的類型。在vc中默認是4位元組對齊的,GNU gcc 是默認4位元組對齊。
4、 更改C編譯器的預設位元組對齊方式
在預設情況下,C編譯器為每一個變數或是數據單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變預設的對界條件:
使用偽指令#pragma pack (n),C編譯器將按照n個位元組對齊。
使用偽指令#pragma pack(),取消自定義位元組對齊方式。
另外,還有如下的一種方式:
__attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。 ·
attribute ((packed)),取消結構在編譯過程中的優化對齊,按照實際佔用位元組數進行對齊。
5、 舉例說明
例1
struct test
{
char x1;
short x2;
float x3;
char x4;
};
1
2
3
4
5
6
7
1
2
3
4
5
6
7
由於編譯器默認情況下會對這個struct作自然邊界(有人說「自然對界」我覺得邊界更順口)對齊,結構的第一個成員x1,其偏移地址為0,占據了第1個位元組。第二個成員x2為short類型,其起始地址必須2位元組對界。
因此,編譯器在x2和x1之間填充了一個空位元組。結構的第三個成員x3和第四個成員x4恰好落在其自然邊界地址上,在它們前面不需要額外的填充位元組。
在test結構中,成員x3要求4位元組對界,是該結構所有成員中要求的最大邊界單元,因而test結構的自然對界條件為4位元組,編譯器在成員x4後面填充了3個空位元組。整個結構所佔據空間為12位元組。
例2
#pragma pack(1) //讓編譯器對這個結構作1位元組對齊
struct test
{
char x1;
short x2;
float x3;
char x4;
};
#pragma pack() //取消1位元組對齊,恢復為默認4位元組對齊
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
這時候sizeof(struct test)的值為8。
例3
#define GNUC_PACKED __attribute__((packed))
struct PACKED test
{
char x1;
short x2;
float x3;
char x4;
}GNUC_PACKED;
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
這時候sizeof(struct test)的值仍為8。
二、深入理解
①什麼是位元組對齊,為什麼要對齊?
現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變數的訪問可以從任何地址開始。
但實際情況是在訪問特定類型變數的時候經常在特定的內存地址訪問,這就需要各種類型數據按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
對齊的作用和原因:各個硬體平台對存儲空間的處理上有很大的不同。一些平台對某些特定類型的數據只能從某些特定地址開始存取。比如有些架構的CPU在訪問一個沒有進行對齊的變數的時候會發生錯誤,那麼在這種架構下編程必須保證位元組對齊.其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對數據存放進行對齊,會在存取效率上帶來損失。比如有些平台每次讀都是從偶地址開始,如果一個int型(假設為32位系統)如果存放在偶地址開始的地方,那麼一個讀周期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀周期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit數據。顯然在讀取效率上下降很多。
②位元組對齊對程序的影響:
先讓我們看幾個例子吧(32bit,x86環境,gcc編譯器):
設結構體如下定義:
struct A
{
int a;
char b;
short c;
};
struct B
{
char b;
int a;
short c;
};
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
現在已知32位機器上各種數據類型的長度如下:
char:1(有符號無符號同)
short:2(有符號無符號同)
int:4(有符號無符號同)
long:4(有符號無符號同)
float:4 double:8
那麼上面兩個結構大小如何呢?
結果是:
sizeof(strcut A)值為8
sizeof(struct B)的值卻是12
Ⅶ c語言結構體對齊的問題。
structdata 是8位元組對齊
{intcat; 4
inta[5]; 4*5=20
doubledog; 8
}size是32 32剛好是8的倍數
structdata 8位元組對齊
{intcat; 4
inta[6]; 4*6=24
doubledog; 8
},size是40.
要是說數據對齊估計你想像不來
你就這么記 真實大小要湊成幾位元組對齊那個幾的倍數
例如第二個真實是36 而比36大的8的倍數最近的就是40
畫圖的話我試著畫一個
Ⅷ 結構體內部指針變數 對齊問題
你的代碼沒有問題
不過你對於位元組對齊的理解不是很正確
就算你指明了#pragma pack(1)按1位元組對齊,編譯器還是會4位元組對齊
1位元組對齊只是個建議,編譯器會根據結構體內的數據決定到底按幾位元組對齊
Ⅸ 關於C語言中的結構體位元組對齊
仔細看一下書中的說明吧,這三言兩語介紹起來有點累
或從網上查閱相關的技術資料,有詳細描述。
一般簡單來說,結構體從第一個變數開始檢查空間的「對齊位元組數」,
默認以第一個位元組大小作為對齊位元組數,如果遇上的下一個位元組與當前對齊位元組數不同時,就按兩者中較大的來進行結構體空間分配,接下來的對齊就全按此值來對齊,直到再遇上不同的才進行檢查或改變。
Ⅹ 怎樣設置gcc編譯出程序的struct member align
為了解決Unix自定義結構在GCC優化編譯中對齊問題,一般解決辦法是用如下宏封裝
自定義結構
#pragma pack(1)
struct my_arphdr
{
};
#pragma pack()
如果是SPARC/Solaris,還可以這樣
struct my_arphdr
{
} __attribute__ ((packed));
兩種辦法其實都可以用在Unix系統/GCC編譯器中。
D: mbuf@smth
關於結構中位元組對齊問題,相應編譯器選項為
GCC/G++ : -fpack-struct
Sun Workshop cc/CC: -misalign
最好不這樣做,會大大降低程序效率,特別在某些架構中。應該嘗試用位操作來處理。
D: Unknown@smth
GCC可以這么解決
#ifdef __GCC__
#define PACKED __attribute__((__packed__))
#else
#define PACKED
#endif
struct msg
{
u_int16_t PACKED first;
...
};
還是 VC 簡單,#include <pshpack1.h> 就搞定了
A: gfh_nuaa
DEC : #pragma pack(1)
SUN : #pragma pack(1)
AIX : 編譯時 -q align=packed
HP-UX : #pragma pack 1
D: Joe Durusau
在 Visual C++ 中,使用 "-ZP1" 就可以讓編譯器對自定義結構進行單位元組對齊,實
際就是取消了對齊優化。
A: [email protected] 2001-12-20 13:09
1) 結構內部成員的pack
struct foo
{
char a;
int b __attribute__ ((packed));
};
2) 整個結構的pack
struct foo
{
char a;
int b;
}__attribute__ ((packed));
3) 文件范圍的pack
#pragma pack(1)
struct foo
{
char a;
int b;
};
... ...
4) 編譯選項的pack
-fpack-struct
但這是最危險的做法,因為這樣做可能會使庫函數和你的程序對結構內成員的偏移理
解不一致。