C语言中的struct结构体对齐问题
C語言中的數據對齊問題
數據對齊:現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定變量的時候經常在特定的內存地址訪問,這就需要各類型數據按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
以下面的代碼為例:
#include<stdio.h> typedef struct {char a;short b;int c;
}test;int main(){test t;t.a='a';t.b=0x12;t.c=0x34;printf("test結構體的長度:%ld\n",sizeof(test));char*p=(char*)&t;for(int i=0;i<sizeof(test);i++,p++){printf("%02x ",*p);}printf("\n");printf("成員a起始地址:0x%p\n成員b起始地址:0x%p\n成員c起始地址:0x%p\n",&t.a,&t.b,&t.c);return 0;
}
代碼效果:
和一般認為的7字節長度不同,test結構體實際的長度位為8字節。可以從代碼結果中看出成員a和成員b之間多了一個保留字節,因此導致了結構體長度變為了8。結構體在編譯過程中發生了數據對齊。
對齊方式
數據對齊的方式如下:
1、結構體中元素是按照定義順序一個一個放到內存中去的,但并不是緊密排列的。從結構體存儲的首地址開始,每一個元素放置到內存中時,它都會認為內存是以它自己的大小來劃分的,因此元素放置的位置一定會在自己寬度的整數倍上開始(以結構體變量首地址為0計算)。
2、在經過上述分析后,檢查計算出的存儲單元是否為所有元素中最寬的元素的長度的整數倍,是,則結束;若不是,則補齊為它的整數倍。
舉個例子:
struct new{
int a;
char b;
int c;
};
由上述易推知結構體new的長度為12個字節。
如果想要編譯過程中取消數據對齊,有如下方式:
1、加入預編譯選項#pragma pack(n)
n=1時,表示全緊湊,此時struct中不會多出保留字節。
2、linux中gcc選項 “-fpack-struct”
3、linux中使用__attributte__((packed))聲明。示例:
struct new{
int a;
char b;
int c;
}_attribute_((packed))
因此在C語言編程中需要小心對結構體使用memcpy()等內存函數,地址不小心就會弄錯!
總結
以上是生活随笔為你收集整理的C语言中的struct结构体对齐问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matlab实现连通域标记算法求图像连通
- 下一篇: C语言读取bmp图像并做简单显示