C中结构的实际大小是多少

时间:2012-01-24 07:06:20

标签: c gcc ubuntu

  

可能重复:
  struct sizeof result not expected
  Struct varies in memory size?

以下是在Ubuntu Server 11.10 for i386机器上编译的代码:

// sizeof.c
#include <stdio.h>
#include <malloc.h>


int main(int argc, char** argv){
        printf("int's size: %d bytes\n", sizeof(int));
        printf("double's size: %d bytes\n", sizeof(double));
        printf("char's size: %d bytes\n", sizeof(char));
        printf("\n");

        printf("char pointer's size: %d\n", sizeof(char *));
        printf("\n");

        struct Stu{
                int id;
                char* name;
                char grade;
                char sex;
        //      double score;
        };
        printf("struct Stu's pointer's size : %d\n",sizeof(struct Stu *));

        struct Stu stu;
        stu.id=5;
        stu.name="Archer";
        stu.grade='A';
        stu.sex='M';
        printf("Stu(int,char*, char,char)'s size: %d bytes\n", sizeof(struct Stu));
        printf("Stu(5,\"Archer\",'A','M')'s size: %d bytes\n",sizeof(stu));
}

编译:

`gcc -o sizeof sizeof.c`

输出:

int's size: 4 bytes
double's size: 8 bytes
char's size: 1 bytes

char pointer's size: 4

struct Stu's pointer's size : 4
Stu(int,char*, char,char)'s size: 12 bytes
Stu(5,"Archer",'A','M')'s size: 12 bytes

我的问题是为什么struct Stu的大小为12,而不是sizeof(int) + sizeof(char *) + sizeof(char) + sizeof(char) = 4 + 4 + 1 + 1 = 10. When you put a double member into struct Stu , sizeof(struct Stu)`的大小为20。

2 个答案:

答案 0 :(得分:4)

要计算用户定义类型的大小,编译器会考虑复杂的用户定义数据结构所需的任何对齐空间。这就是为什么C中结构的大小可以大于其成员大小的总和。例如,在许多系统上,以下代码将打印8:

参考http://en.wikipedia.org/wiki/Sizeof

假设您具有以下结构:

struct A1
{
  char a[2];
  int b;
};

你可以认为sizeof(A1)等于6,但事实并非如此。它等于8.编译器在成员'a'和'b'之间插入2个虚拟字节。

原因是编译器会将成员变量与包大小的倍数或类型大小的倍数对齐,以最小者为准。

visual studio中的默认包大小为8个字节。

'b'是整数类型,宽度为4个字节。 'b'将与2的最小值对齐,即4个字节。 “a”是1,2,3或4字节宽是无关紧要的。 'b'将始终在同一地址上对齐。

参考for more details

答案 1 :(得分:1)

数据必须正确对齐以获得不错的效率,因此编译器可以自由地在结构内部添加填充(除了开始之外的任何地方)。

通常,N字节类型(对于1,2,4,8,16字节)在N字节地址边界上对齐。

因此,对于32位编译,结构具有:

    int id;          // offset =  0, size = 4
    char* name;      // offset =  4, size = 4
    char grade;      // offset =  8, size = 1
    char sex;        // offset =  9, size = 1
    double score;    // offset = 16, size = 8

总大小为24.请注意,即使您将double移动到结构的前面,或者移到结构的前面,或者移到名称之后,大小仍然是24,因为所有元素都是结构的数组必须正确对齐,因此将至少有6个字节的填充。 (有时,只需要在4字节边界上对齐一个double;然后填充将是2个字节而不是6个。)

即使没有double成员,结构也必须是12个字节长,以便id正确对齐数组中的额外元素 - 将有2个字节的填充。

有些编译器为编程人员提供了一条名为#pragma pack或其左右的绳索,一些程序员有机会用这样提供的绳索悬挂自己。