1、结构体字节对齐遵循的原则
-
某数据类型的变量存放的地址需要按有效对齐字节剩下的字节数可以被该数据类型所占字节数整除,char可以放在任意位置,int存放在剩下字节数可以被4整除的位置。这个对齐规则是内部一定的
-
结构体的大小一定要为有效对齐值的整数倍
-
当没有明确指明时,以结构体中最长的成员的长度来对齐,注意!数组成员个数并不影响有效对齐值,只是数组类型大小和其他成员比较取最大。但是当然数组成员总占用内存也要遵循字节对齐
-
当用#pragma pack(n)指定时,以n和最长成员中长度较小的值来对齐。可以增加可以减少。
-
__attribute__((__n__)) ,强制按照该值来对齐 __attribute__ ((aligned (4))) attribute((aligned(x)))定义的是最小对齐边界.只能增加。
typedef struct test{ char a; double b; char c; int d; } __attribute__ ((aligned (1))) test ; // sizeof 显示 24
并没有按照1字节对齐
拓展 typde struct 和struct成区别:
struct Student
{
int a;
}stu1;//stu1是一个变量
typedef struct Student2
{
int a;
}stu2;//stu2是一个结构体类型
使用时可以直接访问stu1.a//当成成员函数的调用
但是stu2则必须先 stu2 s2;
然后 s2.a=10;
引用大佬的一个代码案例进行思考
#include <stdio.h>
typedef struct test{
char a;
double b;
char c;
int d;
} __attribute__ ((aligned (16))) test ;
int main() {
test a ;
printf("%d\n",sizeof(test));
printf("%f\n",(unsigned long long)&a/16.); // 32
return 0;
}
#include <stdio.h>
typedef struct test{
char a;
double b;
char c;
int d;
} test __attribute__ ((aligned (16)));
int main() {
test a ;
printf("%d\n",sizeof(test));
printf("%f\n",(unsigned long long)&a/16.); // 24
return 0;
}
问题出在哪里呢
我的思考
(1) 例题1 修饰的是 struct test ,是一个类型,本身大小是24 ,但依照16对齐时,后面空着,故补齐 形成2个16.且最小对齐方式是16
(2) 例题2 修饰的是test 应该修饰的是一个变量。变量本质上还是24 故没有改变