含有数组的内存对齐的例子,不晓得是怎么对齐的。

小湿哥 2013-07-07 07:18:18

class A
{
char a,b;
char arr[5];
}
//这个sizeof(A)=7.。1+1+5 = 7.。对齐单位为1字节。这个可以理解。

class B
{
int a,b;
char arr[5];
}
//这个sizeof(B) = 16.. 是怎么对齐的? 数组占了8个字节?。为什么?
...全文
868 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2013-07-08
  • 打赏
  • 举报
回复
引用 7 楼 adlay 的回复:
[quote=引用 3 楼 jacicson1987 的回复:] [quote=引用 1 楼 adlay 的回复:] 结构体的对齐以它成员类型里面最大的对齐 B 里面最大的是 int, 4 字节,所以 B 也要以 4 字节对齐 这是为了在你定义 B 的数组时能保证每个元素里面每个成员能对齐。
你这等于什么都没说。 char arr[5]; 若是每个元素都和4 对齐,那就是 20个字节;一共也就是28个字节了,不对。[/quote] 结构体对齐是指结构体需要填充来满足条件,是在成员对齐的基础上的, 结构体总大小按最大的成员对齐,也就是总大小是最大成员大小的倍数,这里是 4 的倍数 如果 int 改成 short, 大小就是 10,满足 2 的倍数就行 [/quote] 其实基本原则还是相同的, 就是要保证每个成员访问的时候, 它的地址需要是它类型大小的整数倍. 这里说的类型是指基本类型, 复合类型的话不是用类型的大小, 是类型的对齐大小. 数组也是复合类型. char x[10]; 的大小是 10, 但是对齐满足地址是 1 的整数倍就行. int x[10]; 满足地址是 4 的整数倍. 基于这个原则, 我们定义 B 的数组, B b[10]; 如果没有结构体填充来对齐, 比如它的大小是 13, 那么 &(b[1].a) - &(b[0].a) 就等于 13, 就无法同时保证 b[0].a 和 b[1].a 的地址都是 4 的整数倍了! 所以 B 的对齐大小是它最大成员类型的大小, 也就是 4. 如果 B 的首地址能保证是 4 的整数倍, 里面的 a 成员就可以做到是 4 的整数倍了. 然后继续: class C { char x; B b; }; 这里面的 b 怎么对齐呢? 还是要求 b 的地址要是 B 的对齐大小 4 的整数倍. 而不是要求是它类型本身的大小 16 的整数倍.
赵4老师 2013-07-08
  • 打赏
  • 举报
回复
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD  { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1  { int a; char b[13]; double c;};
#pragma pack(2)
struct A2  { int a; char b[13]; double c;};
#pragma pack(4)
struct A4  { int a; char b[13]; double c;};
#pragma pack(8)
struct A8  { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
    printf("AD.a %d\n",field_offset(AD,a));
    printf("AD.b %d\n",field_offset(AD,b));
    printf("AD.c %d\n",field_offset(AD,c));
    printf("\n");
    printf("A1.a %d\n",field_offset(A1,a));
    printf("A1.b %d\n",field_offset(A1,b));
    printf("A1.c %d\n",field_offset(A1,c));
    printf("\n");
    printf("A2.a %d\n",field_offset(A2,a));
    printf("A2.b %d\n",field_offset(A2,b));
    printf("A2.c %d\n",field_offset(A2,c));
    printf("\n");
    printf("A4.a %d\n",field_offset(A4,a));
    printf("A4.b %d\n",field_offset(A4,b));
    printf("A4.c %d\n",field_offset(A4,c));
    printf("\n");
    printf("A8.a %d\n",field_offset(A8,a));
    printf("A8.b %d\n",field_offset(A8,b));
    printf("A8.c %d\n",field_offset(A8,c));
    printf("\n");
    printf("A16.a %d\n",field_offset(A16,a));
    printf("A16.b %d\n",field_offset(A16,b));
    printf("A16.c %d\n",field_offset(A16,c));
    printf("\n");
    return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//
//A1.a 0
//A1.b 4
//A1.c 17
//
//A2.a 0
//A2.b 4
//A2.c 18
//
//A4.a 0
//A4.b 4
//A4.c 20
//
//A8.a 0
//A8.b 4
//A8.c 24
//
//A16.a 0
//A16.b 4
//A16.c 24
//
//
如此美丽的你 2013-07-07
  • 打赏
  • 举报
回复
www_adintr_com 2013-07-07
  • 打赏
  • 举报
回复
引用 3 楼 jacicson1987 的回复:
[quote=引用 1 楼 adlay 的回复:] 结构体的对齐以它成员类型里面最大的对齐 B 里面最大的是 int, 4 字节,所以 B 也要以 4 字节对齐 这是为了在你定义 B 的数组时能保证每个元素里面每个成员能对齐。
你这等于什么都没说。 char arr[5]; 若是每个元素都和4 对齐,那就是 20个字节;一共也就是28个字节了,不对。[/quote] 结构体对齐是指结构体需要填充来满足条件,是在成员对齐的基础上的, 结构体总大小按最大的成员对齐,也就是总大小是最大成员大小的倍数,这里是 4 的倍数 如果 int 改成 short, 大小就是 10,满足 2 的倍数就行
qzf362269994 2013-07-07
  • 打赏
  • 举报
回复
有些编译器为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。 第二个中 字节边界数为4所以sizeof(arr)的对4向上取整
昵称很不好取 2013-07-07
  • 打赏
  • 举报
回复
你可以试一下, class A { char a,b; char arr[5]; } class B { A objA; int a,b; char arr[5]; } sizeof(B)不会是7 + 16了。
引用 4 楼 jacicson1987 的回复:
[quote=引用 2 楼 thefirstz 的回复:] sizeof的结果一般会是结构体中占用最多内存的元素所占内存的整数倍,或是4的整数倍,这里的4取决于机器的位宽,32位机器一般是4个字节,因为总线能一下子读取这么大小的数据,否则读取性能可能会有问题。 sizeof(A) == 7,楼主懂了 sizeof(B) == sizeof(int) + sizeof(int) + sizeof(arr)的对4向上取整 = 4 + 4 + 8 = 16
果然不是简单的 数组元素的 对齐。。 以此类推,结构体中包含结构体,是按照元素,还是总的?[/quote]
小湿哥 2013-07-07
  • 打赏
  • 举报
回复
引用 2 楼 thefirstz 的回复:
sizeof的结果一般会是结构体中占用最多内存的元素所占内存的整数倍,或是4的整数倍,这里的4取决于机器的位宽,32位机器一般是4个字节,因为总线能一下子读取这么大小的数据,否则读取性能可能会有问题。 sizeof(A) == 7,楼主懂了 sizeof(B) == sizeof(int) + sizeof(int) + sizeof(arr)的对4向上取整 = 4 + 4 + 8 = 16
果然不是简单的 数组元素的 对齐。。 以此类推,结构体中包含结构体,是按照元素,还是总的?
小湿哥 2013-07-07
  • 打赏
  • 举报
回复
引用 1 楼 adlay 的回复:
结构体的对齐以它成员类型里面最大的对齐 B 里面最大的是 int, 4 字节,所以 B 也要以 4 字节对齐 这是为了在你定义 B 的数组时能保证每个元素里面每个成员能对齐。
你这等于什么都没说。 char arr[5]; 若是每个元素都和4 对齐,那就是 20个字节;一共也就是28个字节了,不对。
昵称很不好取 2013-07-07
  • 打赏
  • 举报
回复
sizeof的结果一般会是结构体中占用最多内存的元素所占内存的整数倍,或是4的整数倍,这里的4取决于机器的位宽,32位机器一般是4个字节,因为总线能一下子读取这么大小的数据,否则读取性能可能会有问题。 sizeof(A) == 7,楼主懂了 sizeof(B) == sizeof(int) + sizeof(int) + sizeof(arr)的对4向上取整 = 4 + 4 + 8 = 16
www_adintr_com 2013-07-07
  • 打赏
  • 举报
回复
结构体的对齐以它成员类型里面最大的对齐 B 里面最大的是 int, 4 字节,所以 B 也要以 4 字节对齐 这是为了在你定义 B 的数组时能保证每个元素里面每个成员能对齐。

65,189

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧