Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中结构的大小;GCC与实际计算_C_Struct_Padding - Fatal编程技术网

C中结构的大小;GCC与实际计算

C中结构的大小;GCC与实际计算,c,struct,padding,C,Struct,Padding,根据, 在32位gcc编译器上,sizeof(T)将返回me16。因为对齐是4,所以为了计算,我应该这样做:3+(1)+2+(2)+4+3+(1),其中括号表示填充物。GCC对此表示赞同 基于这个逻辑,我自己做了一些实践,提出了另一个问题 typedef struct{ char buf1[9]; unsigned short s; double d; char buf2[3]; } S; 在32位gcc编译器上,sizeof应返回me32。因为对齐是8,所以为

根据,

在32位gcc编译器上,sizeof(T)将返回me16。因为对齐是4,所以为了计算,我应该这样做:
3+(1)+2+(2)+4+3+(1)
,其中括号表示填充物。GCC对此表示赞同

基于这个逻辑,我自己做了一些实践,提出了另一个问题

typedef struct{
    char buf1[9];
    unsigned short s;
    double d;
    char buf2[3];
} S;
在32位gcc编译器上,sizeof应返回me32。因为对齐是8,所以为了计算,我应该这样做:
8+1+2+(5)+8+3+(5)
。然而,gcc告诉我sizeof(S)是24

我认为这是因为优化,然而,在gcc中弄乱了-O0标志之后,sizeof(s)仍然会产生24

这是怎么回事

我使用这个
gcc-m32 main.c
来编译

提前感谢

编辑:如果我理解正确,我的计算和GCC的计算不匹配的原因是因为每个编译器都有自己处理结构数据的方法。那么,计算结构大小的通用方法是什么?或者更确切地说,计算结构大小的原始方法是什么

那么,计算结构大小的通用方法是什么?或者更确切地说,计算结构大小的原始方法是什么

没有通用的方法。也没有真正的“原创”方式,因为C是在20世纪70年代创建的,当时PDP-11s是一种东西,C直到1989年才被正式指定。它是由实现定义的,并且随着平台的不同而变化(我不仅仅是轻率;它确实在平台和实现之间变化(甚至编译器标志!)


如果您的教授希望您计算结构的大小,那么他或她必须提供每种数据类型所需的对齐方式。如果他们不这样做,那么他们的问题就不够明确(事实上,有无数不同的答案可以被认为是“正确的”)。

我编写了下面的代码来检查结构中每个元素的地址

#include <stdio.h>

typedef struct{
    char buf1[9];
    unsigned short s;
    double d;
    char buf2[3];
} S;

int  main()
{
    S S1;
    S *Sptr = &S1;
    printf ("\n sizeof (S) is %d",sizeof(S));
    printf ("\n Buf1 --> %d",(char*) &(Sptr->buf1[0]) - (char*)Sptr);
    printf ("\n s    --> %d",(char*) &(Sptr->s) - (char*)Sptr);
    printf ("\n d    --> %d",(char*) &(Sptr->d) - (char*)Sptr);
    printf ("\n Buf2 --> %d",(char*) &(Sptr->buf2[0]) - (char*)Sptr);
    return 0;
}

短字符位于字节10,因此它在2字节边界上对齐。double位于16m,并在8字节边界对齐。最后一个结构也被填充为8字节。

你的措辞很混乱:你说GCC将sizeof(S)作为24,但你说“sizeof(S)仍然导致32”。我认为你的问题是无效的,你只是把自己弄糊涂了。公开使用和一些简单的输出语句可能会给你一些答案。我想下面的填充
S::buf1
可能会让你感到惊讶。。值得注意的是,在x86上,默认情况下,GCC将在4字节边界上对齐
double
,而不是在8字节边界上对齐。@Jieqin,一般来说,您不需要手动计算结构的大小。您可以依靠
sizeof
来确定所需的大小。能够预测
sizeof
@Jieqin的结果很少重要:
buf1
之后有1字节的填充,因为
s
需要在2字节的边界上对齐
short
s通常在2字节边界上对齐。我也做了类似的事情,使用stddef.h中的offsetof函数来生成所使用的地址。我得到了和你一样的答案。谢谢谢谢你的澄清!
#include <stdio.h>

typedef struct{
    char buf1[9];
    unsigned short s;
    double d;
    char buf2[3];
} S;

int  main()
{
    S S1;
    S *Sptr = &S1;
    printf ("\n sizeof (S) is %d",sizeof(S));
    printf ("\n Buf1 --> %d",(char*) &(Sptr->buf1[0]) - (char*)Sptr);
    printf ("\n s    --> %d",(char*) &(Sptr->s) - (char*)Sptr);
    printf ("\n d    --> %d",(char*) &(Sptr->d) - (char*)Sptr);
    printf ("\n Buf2 --> %d",(char*) &(Sptr->buf2[0]) - (char*)Sptr);
    return 0;
}
sizeof (S) is 32
Buf1 --> 0
s    --> 10
d    --> 16
Buf2 --> 24