struct size与typedef版本不同?

时间:2010-05-06 03:41:30

标签: c++ struct

我的代码中有以下结构声明和typedef:

struct blockHeaderStruct {
    bool allocated;
    unsigned int length;
};
typedef struct blockHeaderStruct blockHeader;

当我执行sizeof(blockheader)时,我得到4个字节的值,但是当我执行sizeof(struct blockHeaderStruct)时,我得到8个字节。

为什么会这样?为什么我没有回来呢?

6 个答案:

答案 0 :(得分:4)

首先,你不能sizeof(blockHeaderStruct)。那根本就不会编译。你可以做的是sizeof(struct blockHeaderStruct),结果确实可以给你8个字节。

其次,从sizeof(blockheader)获得不同的结果是不太可能的。根据您对sizeof(blockHeaderStruct)的引用(再次,甚至不会编译)来判断您对问题的描述是不准确的。仔细看看你到底在做什么。最有可能的是,你正在使用sizeof指针类型(它给你4),而不是结构类型。

无论如何,请尝试发布实际代码。

答案 1 :(得分:3)

查看结构的定义,您有1个字节的值,后跟4个字节的整数。这个整数需要在4字节边界上分配,这将强制编译器在1字节bool之后插入3字节填充。这使得struct的大小为8字节。为避免这种情况,您可以更改结构中元素的顺序。

对于两个返回不同值的sizeof调用,你确定这里没有拼写错误,你没有使用指针大小或不同类型或某个整数变量。

答案 2 :(得分:1)

最可能的情况是,您实际上是在32位系统上查看指针的大小,而不是struct

但是,int可能是2个字节(16位)。在这种情况下,结构的预期大小为4:

  • int
  • 的2个字节
  • bool
  • 的1个字节
  • 向上舍入到下一个2的倍数,因为结构的大小通常舍入为其最大基元成员的大小的倍数。

但是,鉴于sizeof(blockHeaderStruct) != sizeof(struct blockHeader),没有什么可以解释typedef。这完全不可能。

答案 3 :(得分:0)

  

我实际上直接复制了该代码段   来自我的源文件。

行。

  

当我做sizeof(blockheader)时,我明白了   返回4个字节的值

看起来blockheader在某处是typedef,其类型占用4个字节,或者它的类型需要4个字节对齐。

如果您尝试使用sizeof(blockHeader),您将获得类型。

  

当我做sizeof(blockHeaderStruct)时,我   得到8个字节。

对齐很重要的原因是如果你需要一个blockHeaders数组,那么你可以计算出你需要多少内存。或者如果你有一个数组并且需要计算要复制的内存量,你可以计算它。

如果要将所有struct成员对齐到1的倍数而不是4的地址,或者代替编译器的默认值,编译器可能会提供#pragma来执行此操作。然后,您将节省内存,但访问可能会更慢,以便访问未对齐的数据。

答案 4 :(得分:0)

结构分配通常发生在4字节边界上。也就是说,在开始下一个数据类型之前,编译器会将结构中的数据类型填充到4字节边界。鉴于这是c ++(bool是sizeof 1)而不是c(bool需要#define作为某种东西)

    struct blockHeaderStruct {
       bool allocated;         // 1 byte followed by 3 pad bytes
       unsigned int length;    // 4 bytes
    };
    typedef struct blockHeaderStruct blockHeader;
    typedef struct blockHeaderStruct *blockHeaderPtr;

将导致sizeof操作:

sizeof(blockHeader) == 8
sizeof(struct blockHeader) == 8
sizeof(blockHeaderPtr) == 4
  

(注意:最后一个条目是8   64位编译器。 )

前两行代码之间的大小应该没有差异。 typedef仅为现有类型指定别名。第三种是使用指针的大小,该指针在32位机器中为4字节,在64位机器上为8字节。


要解决此问题,只需在定义结构之前应用#pragma pack指令。这会强制编译器打包在指定的边界上。通常设置为1,2或4(尽管4通常是默认值,不需要设置)。

#include <stddef.h>
#include <stdio.h>

#pragma pack(1)
struct blockHeaderStruct {
    bool allocated;
    unsigned int length;
};
typedef struct blockHeaderStruct blockHeader;

int main()
{
    printf("sizeof(blockHeader) == %li\n", sizeof(blockHeader));
    printf("sizeof(struct blockHeader) == %li\n", sizeof(struct blockHeaderStruct));

    return 0;
}
  

用g ++编译(Ubuntu   4.4.1-4ubuntu9)4.4.1

结果:

sizeof(blockHeader) == 5  
sizeof(structblockHeader) == 5

您通常不需要此指令。只记得有效地打包你的结构。将较小的数据类型组合在一不要交替&lt; 4字节数据类型和4字节数据类型,因为您的结构将主要是未使用的空间。这可能会导致网络相关应用程序不必要的带宽

答案 5 :(得分:-1)

有些编译器会优化以始终按2的幂分配数据(4个停留4,但5个舍入到8)。