C中sizeof的内部机制?

ssj*_*ssj 42 c gcc sizeof flexible-array-member

我使用sizeof来获取C中结构的大小,但我得到的结果是意外的.

struct sdshdr {
    int len;
    int free;
    char buf[];
};


int main(){
    printf("struct len:%d\n",(sizeof(struct sdshdr)));
    return 0;
} //struct len:8, with or without buf
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么不buf占用任何空间,为什么int64位CPU上的类型大小仍为4?

这是输出gcc -v:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix  
Run Code Online (Sandbox Code Playgroud)

Lun*_*din 52

[]是一个灵活的数组成员.它们不计入结构的总大小,因为C标准明确地这样说:

6.7.2.1/18

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型; 这被称为灵活的阵列成员.在大多数情况下,将忽略灵活数组成员.特别地,结构的尺寸好像省略了柔性阵列构件,除了它可以具有比省略意味着更多的拖尾填充.

这是故意设计的,因为灵活的数组成员的目的是允许您在结构之后动态分配尾随数据.(当结构是文件头,协议头等时)

示例包括有关非标准gcc扩展和旧前C99"struct hack"的讨论.

  • @Floris`malloc(sizeof(mystruct)+ sizeof(mystruct.flexiblearray [0])*numelements)`是的,你必须使用`malloc`或`alloca`; 常规的堆栈分配结构不会为该数组保留任何空间. (7认同)
  • @Floris`buf`不是指针; 它只是结构的结尾.默认情况下,`buf [0]`超出了struct的空间; 在结构之外的`malloc`数据是你的工作,以存储你想要放在`buf`中的任何内容. (3认同)
  • @Ruslan如果您动态分配结构,则不是如我链接的示例所示. (2认同)

Ark*_*kku 12

从C99开始,可以省略结构末尾的数组大小.出于sizeof(struct)这个目的,数组似乎没有大小(虽然它的存在可能会为结构添加一些填充),但意图是它的长度是灵活的,即,当为结构分配空间时,必须分配所需的数量最后阵列的额外空间.(为了避免超出范围,数组的实际分配长度应存储在某处.)

在C99之前,在结构的末尾有一个大小为1的数组(或编译器允许的0),然后为它分配更多的空间是一个相当普遍的黑客,所以C99通过引入灵活的数组明确允许这种做法没有给出大小的成员.