C的字节对齐和位域操作
作者:互联网
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
标签:__,字节,int,attribute,char,对齐,位域,bit 来源: https://blog.csdn.net/weixin_44537992/article/details/106477059