结构数组的大小

size of struct-array

本文关键字:数组 结构      更新时间:2023-10-16

如果我有一个结构 A 定义为:

struct A {
    char* c;
    float f;
    int i;
};

和一个数组

A col[5];

那为什么

sizeof(*(col+0)) 

16?

在您的平台上,需要 16 个字节来保存该结构,该结构的类型为 A

您应该记住,*(col+0)col[0] 相同,因此它只是结构之一,而不是整个数组。如果需要数组的大小,可以使用sizeof(col)

可能是因为:

  • 您在 64 位平台上,char*需要 8 个字节,而intfloat需要 4 个字节,
  • 您在 32 位平台上,char*需要 4 个字节,但您的编译器决定,如果数组在那里删除 4 个字节的填充,数组会更快。在大多数编译器上,填充可以分别通过 #pragma 包(push,1(和 #pragma 包(pop(来控制。

如果要确定,可以使用offsetof(在GCC上(或创建一个对象并检查其成员字段的地址,以检查实际填充了哪些字段以及填充了多少。

对于初学者来说,您的原始声明不正确(现在已经在问题编辑中修复了这个问题(。 A是类型的名称;要声明一个名为 col 的数组,您需要

A col[5];

col A[5];

sizeof(*(col+0))sizeof col[0]相同,与sizeof (A)相同。

它是 16,因为这是该结构的大小,对于您正在使用的编译器和系统(您尚未提及它是什么(。

我从这个问题中得出的结论是,你期待一些不同的东西,但你没有这么说。

编译器可以在成员之间或在最后一个成员之后插入填充字节,以确保每个成员正确对齐。 我发现 16 字节对于 64 位系统上的结构来说是一个不足为奇的大小——在这种特殊情况下,可能甚至不需要填充。

如果您不知道,sizeof会产生以字节为单位的结果,其中字节通常(但并非总是(为 8 位。

您的问题很可能是您的处理器平台在浮点数上使用 8 字节对齐。 因此,您的 char* 将需要 4(假设您在 32 位系统上(,因为它是一个指针,它是一个地址。 您的浮点数将取 8,而您的 int 将另外取 4 个,总计 16 个字节。

编译器通常会使某些类型在某些字节边界上对齐,以加快正在使用的硬件平台上的计算速度。

例如,如果您这样做了:

struct x {
    char y;
    int z;
};

您的系统(可能(会说 x 的大小为 8,将字符填充到结构内部的整数中。

您可以添加编译指示(取决于实现(来阻止此操作:

#pragma pack(1)
struct x {
    char y;
    int z;
};
#pragma pack(0)

这将使它的大小等于 5。

编辑:这个问题似乎有两个部分。"为什么sizeof(A)等于16?"总的来说,我现在看到这可能是本意要问的问题。相反,我回答的是第二部分,即"为什么sizeof(*(col+0)) == sizeof(A)

col是一个数组。 col + 0 对于数组毫无意义,因此编译器必须先将col转换为指针。那么col实际上只是一个A*.向指针添加零不会更改任何内容。最后,你用*取消引用它,只剩下一个大小为 16 的简单A

简而言之,sizeof(A) == sizeof(*(col+0))

PS:我还没有解决"为什么数组的一个元素占用 16 个字节?其他人对此回答得很好。

在现代 x86-64 处理器上,char* 为 8 个字节,float为 4 个字节,int为 4 个字节。 因此,成员的大小加起来是 16。 你还会期待什么? 有人告诉你指针是 4 个字节吗? 因为这仅适用于 x86-32。