user-0 提问: C语言结构体内存对齐问题

回复:
user: user-1
content: 上面举的例子可能不恰当，sizeof(char)/2 就是0了，不过就是表明一下这个意思 struct A {     int a:1; //a只使用内存的1个bit，但是A也会分配4个字节大小的内存 } A a; printf("%d", sizeof(a));

user: user-1
content: 内存对齐一般是指按字节大小来分配内存，也就是说一般你申请不到占用不满一个字节的内存（即使是用位占用符） 比如 char *c = (char*)malloc(sizeof(char)/2); //想按半个字节来申请内存，但系统实际会自动按一个字节来分配内存 或许有些编译器支持内存压缩之类的设定

user: user-2
content: 这跟编译器，以及项目的设置有关。

user: user-3
content: 不知道，我知道你最后少写个分号

user: user-0
content: 引用 14 楼 真相重于对错的回复:试一下面代码，具体看看输出什么#pragma pack(8) struct A { 	char a; 	int b; 	char c[15]; 	char d[10]; };  int main() { 	cout << "A size 为" << sizeof(A)<<endl; 	cout <<"a 偏移量"<<offsetof(A,a)<< endl; 	cout << "b 偏移量" << offsetof(A, b) << endl; 	cout << "c偏移量" << offsetof(A, c) << endl; 	cout << "d偏移量" << offsetof(A, d) << endl;     return 0; } 编译器 vs2015,你可以编译为32位程序，再把它编译为64位，看看有何区别？ 再修改#progma pack的参数，把它改为1，2，4，8，16 看看有何却别。 非常感谢，已经搞清楚啦

user: user-0
content: 引用 13 楼 5250的回复:[quote=引用 12 楼  的回复:] [quote=引用 10 楼 5250的回复:][quote=引用 7 楼  的回复:] [quote=引用 5 楼 5250的回复:]struct A{      char a;      int b;      char c[15];      char d[10]; }  char a占据一个字节，分配内存时位置是0，1，2，3...分配的。所以此时char a在0的位置。 是int，占据4个字节，分配内存时是0,4,8...分配的，现在0的位置被占据了，所以int b在4的位置，占据4个字节,为4,5,6,7。1,2,3是空的，这就是字节对齐的其中一种。 c[15]和d[10]同理占据[8,22]和[23,32]，此时这个结构体总共占用了33个字节[0,32]，因为字节对齐的原因，总的字节数要是结构体中最大的数据类型字节的整数倍,即4的整数倍，所以33+3=36，这个结构体总共占据36个字节。 明白了，谢谢咯。之前一直纠结为char c数组分配多少空间，它是15个字节，可是直接15个字节也不太方便访问，但我访问的时候又确实是只有15个字节，所以很疑惑15个字节的话cpu要怎么方便访问。[/quote]  数组的话，就成员一个个分配呀   char a[15] 就是连续分配15char型的内存。[/quote] 那cpu想要访问c数组中的数据的话，一下读取四个字节，这样不是会多读取d的一个字节么，为什么不是给c分配16个，这样方便读取c 跟d中的数据么[/quote]  cpu访问的话，也是看数据类型的,int型会从读取4个字节，char型的每次读取一个字节呀[/quote] 非常感谢，明白了，之前进了死胡同，还一直以为会以4字节去访问，char类型的话无论是字符还是数组都会以1字节为单位去访问

user: user-2
content: 试一下面代码，具体看看输出什么#pragma pack(8) struct A { 	char a; 	int b; 	char c[15]; 	char d[10]; };  int main() { 	cout << "A size 为" << sizeof(A)<<endl; 	cout <<"a 偏移量"<<offsetof(A,a)<< endl; 	cout << "b 偏移量" << offsetof(A, b) << endl; 	cout << "c偏移量" << offsetof(A, c) << endl; 	cout << "d偏移量" << offsetof(A, d) << endl;     return 0; } 编译器 vs2015,你可以编译为32位程序，再把它编译为64位，看看有何区别？ 再修改#progma pack的参数，把它改为1，2，4，8，16 看看有何却别。

user: user-4
content: 引用 12 楼  的回复:[quote=引用 10 楼 5250的回复:][quote=引用 7 楼  的回复:] [quote=引用 5 楼 5250的回复:]struct A{      char a;      int b;      char c[15];      char d[10]; }  char a占据一个字节，分配内存时位置是0，1，2，3...分配的。所以此时char a在0的位置。 是int，占据4个字节，分配内存时是0,4,8...分配的，现在0的位置被占据了，所以int b在4的位置，占据4个字节,为4,5,6,7。1,2,3是空的，这就是字节对齐的其中一种。 c[15]和d[10]同理占据[8,22]和[23,32]，此时这个结构体总共占用了33个字节[0,32]，因为字节对齐的原因，总的字节数要是结构体中最大的数据类型字节的整数倍,即4的整数倍，所以33+3=36，这个结构体总共占据36个字节。 明白了，谢谢咯。之前一直纠结为char c数组分配多少空间，它是15个字节，可是直接15个字节也不太方便访问，但我访问的时候又确实是只有15个字节，所以很疑惑15个字节的话cpu要怎么方便访问。[/quote]  数组的话，就成员一个个分配呀   char a[15] 就是连续分配15char型的内存。[/quote] 那cpu想要访问c数组中的数据的话，一下读取四个字节，这样不是会多读取d的一个字节么，为什么不是给c分配16个，这样方便读取c 跟d中的数据么[/quote]  cpu访问的话，也是看数据类型的,int型会从读取4个字节，char型的每次读取一个字节呀

user: user-0
content: 引用 10 楼 5250的回复:[quote=引用 7 楼  的回复:] [quote=引用 5 楼 5250的回复:]struct A{      char a;      int b;      char c[15];      char d[10]; }  char a占据一个字节，分配内存时位置是0，1，2，3...分配的。所以此时char a在0的位置。 是int，占据4个字节，分配内存时是0,4,8...分配的，现在0的位置被占据了，所以int b在4的位置，占据4个字节,为4,5,6,7。1,2,3是空的，这就是字节对齐的其中一种。 c[15]和d[10]同理占据[8,22]和[23,32]，此时这个结构体总共占用了33个字节[0,32]，因为字节对齐的原因，总的字节数要是结构体中最大的数据类型字节的整数倍,即4的整数倍，所以33+3=36，这个结构体总共占据36个字节。 明白了，谢谢咯。之前一直纠结为char c数组分配多少空间，它是15个字节，可是直接15个字节也不太方便访问，但我访问的时候又确实是只有15个字节，所以很疑惑15个字节的话cpu要怎么方便访问。[/quote]  数组的话，就成员一个个分配呀   char a[15] 就是连续分配15char型的内存。[/quote] 那cpu想要访问c数组中的数据的话，一下读取四个字节，这样不是会多读取d的一个字节么，为什么不是给c分配16个，这样方便读取c 跟d中的数据么

user: user-0
content: 引用 4 楼 qybao的回复:上面举的例子可能不恰当，sizeof(char)/2 就是0了，不过就是表明一下这个意思 struct A {     int a:1; //a只使用内存的1个bit，但是A也会分配4个字节大小的内存 } A a; printf("%d", sizeof(a)); get it!

user: user-4
content: 引用 7 楼  的回复:[quote=引用 5 楼 5250的回复:]struct A{      char a;      int b;      char c[15];      char d[10]; }  char a占据一个字节，分配内存时位置是0，1，2，3...分配的。所以此时char a在0的位置。 是int，占据4个字节，分配内存时是0,4,8...分配的，现在0的位置被占据了，所以int b在4的位置，占据4个字节,为4,5,6,7。1,2,3是空的，这就是字节对齐的其中一种。 c[15]和d[10]同理占据[8,22]和[23,32]，此时这个结构体总共占用了33个字节[0,32]，因为字节对齐的原因，总的字节数要是结构体中最大的数据类型字节的整数倍,即4的整数倍，所以33+3=36，这个结构体总共占据36个字节。 明白了，谢谢咯。之前一直纠结为char c数组分配多少空间，它是15个字节，可是直接15个字节也不太方便访问，但我访问的时候又确实是只有15个字节，所以很疑惑15个字节的话cpu要怎么方便访问。[/quote]  数组的话，就成员一个个分配呀   char a[15] 就是连续分配15char型的内存。

user: user-0
content: 引用 2 楼 真相重于对错的回复:这跟编译器，以及项目的设置有关。 是的，我没有表达清楚具体想问的是什么😂

user: user-0
content: 引用 1 楼 老英捉小奇的回复:不知道，我知道你最后少写个分号 感谢指正，疏忽了。

user: user-0
content: 引用 5 楼 5250的回复:struct A{      char a;      int b;      char c[15];      char d[10]; }  char a占据一个字节，分配内存时位置是0，1，2，3...分配的。所以此时char a在0的位置。 是int，占据4个字节，分配内存时是0,4,8...分配的，现在0的位置被占据了，所以int b在4的位置，占据4个字节,为4,5,6,7。1,2,3是空的，这就是字节对齐的其中一种。 c[15]和d[10]同理占据[8,22]和[23,32]，此时这个结构体总共占用了33个字节[0,32]，因为字节对齐的原因，总的字节数要是结构体中最大的数据类型字节的整数倍,即4的整数倍，所以33+3=36，这个结构体总共占据36个字节。 明白了，谢谢咯。之前一直纠结为char c数组分配多少空间，它是15个字节，可是直接15个字节也不太方便访问，但我访问的时候又确实是只有15个字节，所以很疑惑15个字节的话cpu要怎么方便访问。

user: user-5
content: 看你的编译器以及系统。Linux 32位系统是默认以4字节对齐的，对于64位系统，那么应该是8字节对齐； 建议你在自己的环境下写程序，判断一下（sizeof)

user: user-4
content: struct A{      char a;      int b;      char c[15];      char d[10]; }  char a占据一个字节，分配内存时位置是0，1，2，3...分配的。所以此时char a在0的位置。 是int，占据4个字节，分配内存时是0,4,8...分配的，现在0的位置被占据了，所以int b在4的位置，占据4个字节,为4,5,6,7。1,2,3是空的，这就是字节对齐的其中一种。 c[15]和d[10]同理占据[8,22]和[23,32]，此时这个结构体总共占用了33个字节[0,32]，因为字节对齐的原因，总的字节数要是结构体中最大的数据类型字节的整数倍,即4的整数倍，所以33+3=36，这个结构体总共占据36个字节。