关于sizeof
的{{1}}(非)等于其struct
的元素总和,有很多问题。通常这是由于数据对齐。这个问题不与数据对齐有关,所以请假设所有类型的大小都是对齐的倍数(比如说4B)。
正如here所解释的那样,分配一个数组将导致一些元数据存储在分配数组的大小之内。假设我们有以下代码:
sizeof
由于const int size = 10;
struct X {
int someInt;
int array[size];
};
struct Y {
int someInt;
T array[size];
};
在编译时是已知的,因此编译器应足够智能,以确定在size
的情况下不需要存储任何元数据。即使在X
的情况下,编译器也可以足够聪明地遵循这个推理(这里C和C ++之间可能存在差异,因为在C ++中还有调用析构函数的额外要求Y
)的个别实例。
我的问题是:我保证 T
还是编译器特定的?或者更一般地说,是sizeof(X) == (size + 1) * sizeof(int)
?
编辑:希望稍微澄清一下:问题是关于 C和C ++。问这个问题的最初动机是这个。如果我跑
sizeof(Y) == size * sizeof(T) + sizeof(int)
或它在代码中的某个地方是C等价的,它会创建一个大小为X *foo = new X[100];
的连续内存块吗?
答案 0 :(得分:3)
常见实现中的C数组不会在它们周围存储任何元数据,但是,可以将填充添加到结构中,以便a_struct_ptr + 1
具有a_struct
的足够对齐。
对于第一个结构({ int someInt; int array[size]; }
),不需要填充,所以
sizeof(X) == (size + 1) * sizeof(int)
应该坚持(但我不认为编制者有义务保证)。
对于第二个结构,T
和int
的对齐要求可能会导致填充添加到结构中,这会使等式无效。
答案 1 :(得分:0)
元数据可以隐藏在struct
个成员之间。我从来没有看到这种用于元数据,但是编译器可以使用类型的对齐,直到某一点,通过强制int
的对齐来在两个int
成员之间提供不连续的内存。大于int
宽度,例如4个字节。如果编译器将此用于元数据,性能填充或spite,则无关紧要。关键是它可能存在。
C99 / C11提供max_align_t
,因此根据C规范,类型本身不会超过该对齐。
基本对齐由小于或等于所有上下文中实现所支持的最大对齐的对齐表示,等于
_Alignof (max_align_t)
。 §6.2.811dr§6.2.82
max_align_t
这是一种对象类型,其对齐方式与所有上下文中的实现所支持的一致; §7.192
因此,任何小于max_align_t
的结构成员都会受潜在上下文中的填充/元数据 。