为什么空数组的类型在结构的内部和外部具有不同的大小?

烘烤ZQ
#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_tstruct中变量不会在之后紧接堆叠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版本。

埃里克·波斯蒂奇(Eric Postpischil)

这个面试问题探究了候选人在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具有八个字节的对齐要求。无论其对齐要求是什么,编译器都会在成员之间添加足够的未使用字节,cd确保d具有正确的对齐方式。如果确实需要8字节对齐,则必须在后面插入7个字节c,因此直到开头的结构大小d为1 + 3 + 4 + 1 + 7 = 16字节。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么Java具有与C不同的固定数据类型大小

为什么在调用函数之前和函数内部我的go函数参数具有不同的大小?

为什么比较结构数组有不同的结果

什么使用Go中具有空结构的类型?

为什么这两个结构在内存中具有不同的大小?

为什么内部包含类对象数组的构造函数具有空值

为什么不同整数大小的数组具有不同的性能?

为什么Rust具有结构和枚举?

为什么我可以通过返回类型推导从函数外部访问函数内部定义的结构?

为什么sizeof(std :: variant)的大小与具有相同成员的结构的大小相同?

将嵌套的结构数组重塑为具有大小不同的元素的单元格数组

ggplot2:为什么当'size'包含aes内部和外部aes语句时,符号大小会有所不同?

为什么具有相同数据的列表具有不同的大小?

OCaml为什么一个空数组具有多态类型?

如何从Python访问具有固定大小数组的C结构内部数据?

为什么这些约束布局具有不同的大小?

为什么canvas.toBlob和canvas.toDataURL具有不同的返回类型

为什么两个具有相同文本和编码但大小不同的文件?

为什么python具有不同类型的字节

为什么结构体和可变结构体具有不同的默认相等运算符?

为什么内部类和外部类不能具有相同的名称?

为什么Vim颜色在tmux的内部和外部看起来有所不同?

声明内部具有结构数组的结构数组

为什么数组大小初始化在类/ struct / ...内部或外部不同?

为什么允许结构本身具有“指向其自身类型的指针”而不是成员“结构类型(的数组)”本身?

为什么与字符串文字不同,具有单独字符的字符数组不以空终止符结尾?

为什么结构的大小与结构指针的大小不同

为什么具有 1 和 2 秩的非零基数组具有不同的类型?

为什么 foo 函数内部和外部的参数值不同