1、 字節對齊
首先分析字節對齊之前,需要了解概念
- 自身對齊:數據結構自身的大小
- 指定對齊:編譯器或者用戶指定的值,例如__attribute__ ((aligned (1))),設置爲單字節對齊
- 有效對齊:取自身對齊和指定對齊中較小的
分析結構體佔用內存大小要看以下兩個條件
- 對於結構體或者類,要將其補齊爲其有效對齊值的整數倍,結構體的有效對齊值是其最大數據成員的有效對齊值
- 存放成員的起始地址必須是該成員有效對齊值的整數倍
對於位域操作而言,我們需要關心如下:
a. 位域變量的長度不能大於其類型的長度sizeof(類型) ,例如bit_a中char a:10是不行的
b. 位域可以是無名位域,無名位域只能用作填充或調整位置,不能使用
c. 位域結構體的大小必須是其最長基本類型大小的整數倍sizeof(類型),參見foo4
d. 當一個字節不夠放時,可以另起一個字節,也可以有意重新起一個字節,例如如bs
f. 當結構體中有非位域操作時,整個結構體不進行壓縮,建test3
例子1:
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*從下一單元開始存放*/
unsigned c:4
}
例子2:
struct foo4 {
char a : 2;
char b : 3;
int c : 1;
}; //大小爲4
2. 位對齊(__attribute__使用)
按照bit位,內存是連續的,配合__attribute__使用,GNU使用__attribute__選項來設置,例如下面例子中,Test1使用一位對齊
- attribute ((aligned (n))),按照n字節對齊
- attribute ((packed)),對於域是位對齊
#include <stdio.h>
#include <stdlib.h>
typedef struct Test3
{
char a:1;
int b:2;
long c;
}test3;
typedef struct Test2
{
char a:1;
int b:2;
int :1;
}test2;
struct bit{
int a:4;
int b:4;
char c:4;
char d:4;
}bit1; //默認字節對齊
struct bit_a
{
char a:5;
char b:5;
char c:5;
char d:5;
char e:5;
}__attribute__ ((packed)) bit_a1; //位對齊
struct bit_aa
{
char a;
int b;
}__attribute__ ((packed)) bit_aa; //位對齊
typedef struct Test1
{
char a:1;
short b:2;
}__attribute__ ((aligned (1))) test1; //單字節對齊
int main(int argc, char* argv[])
{
fprintf(stderr,"%ld\n %ld\n %ld\n %ld\n %ld\n %ld\n",sizeof(test3),sizeof(test2),sizeof(bit1),sizeof(bit_a1),sizeof(bit_aa),sizeof(test1));
exit(0);
}
~/Videos$ ./io_1
16
4
4
4
5
2