#include <stdio.h>
struct Obj {
char a;
uint32_t b;
uint8_t c;
uint64_t d[0];
};
struct Obj1 {
uint64_t d[0];
};
int main() {
uint64_t a[0];
printf("%d\n", sizeof(Obj)); // 16
printf("%d\n", sizeof(a)); // 16
printf("%d\n", sizeof(Obj1)); // 16
//cout << sizeof(Obj) << endl; // 16
//cout << sizeof(a) << endl; // 0
//cout << sizeof(Obj1) << endl; // 0
}
如上所示,为什么uint64_t
struct中的变量不会在之后紧接堆叠uint8_t
,更奇怪的是空数组在结构外部的大小为零。
这实际上是一个面试问题。解释是这样的,尽管仍然无法理解。
如果没有第四个字段,则应为4 + 4 + 4 = 12,加上第四个字段为16,第四个字段不占用空间,但会告诉编译器对齐8个字节
这种用法经常在内核中使用,例如,可以通过下标直接访问以下内容
Obj o1; uint64_t array[1024]; // In memory, array immediately follows
o1 o1.d[123]; // can access the elements of array
正如评论所指出的,这可能仅适用于C而不是C ++。所以我将代码更改为C版本。
这个面试问题探究了候选人在C标准和特定实现中的对齐和某些语义的知识。
该char a
成员的大小为1(字节),对齐要求为1(字节)。
该uint32_t b
成员的大小为4,通常具有四个字节的对齐要求。为了将其放置在四个字节的倍数的地址上,编译器必须在aftera
和before之前包括三个未使用的字节b
,这些字节正在调用填充字节。至此,该结构需要1 + 3 + 4 = 8个字节。
该uint8_t c
构件具有一个尺寸和对齐要求之一。到目前为止,该结构需要9个字节。
使用uint64_t d[0]
,行为不是由C标准定义的。但是,除非访问员指定了这是关于严格符合标准C的问题,否则回答行为未定义是不充分的,因为C不仅限于标准。还存在C(但不是严格符合)的C和非标准的C变体。GCC支持众所周知的扩展,其中结构的最后一个成员可以声明为具有零元素的数组,并且访调员希望提问者要意识到这一点。
使用这种结构时,程序必须通过将这种空间添加到使用malloc
或类似的内存分配例程进行的请求中,为它希望使用的任何数组元素分配足够的空间。例如,要为基本结构和13个元素分配空间,可以使用malloc(sizeof(struct Obj) + 13 * sizeof(uint64_t))
。
通常,auint64_t
具有八个字节的对齐要求。无论其对齐要求是什么,编译器都会在成员之间添加足够的未使用字节,c
并d
确保d
具有正确的对齐方式。如果确实需要8字节对齐,则必须在后面插入7个字节c
,因此直到开头的结构大小d
为1 + 3 + 4 + 1 + 7 = 16字节。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句