2013-02-04 85 views
1

我在我的项目和特定结构的上下文中使用数据结构,我对结构填充有疑问。首先看下面给出的结构。我使用Visual Studio 2008编译器。关于在C++中的结构填充

typedef struct tagDATA_PACK 
{ 
    DWORD dDataLength; 
    BYTE bFlags; 
    BYTE bAttrib; 
    BYTE bOffset; 
}DATA_PACK; 

问题1:上述结构的大小是多少? 它显示8个字节。它是正确的。但是,

考虑下面给出的修改结构?

typedef struct tagDATA_PACK 
{ 
    DWORD dDataLength; 
    BYTE bFlags; 
}DATA_PACK; 

这里大小与上面的8字节结构相同。 我的疑问是,编译器会在哪里添加额外的3字节? 是BYTE bFlags还是之前?

所有的答案是非常感谢。

回答

4

标准并未指定结构和类的对齐和填充。完全取决于编译器。但是,所有理智的编译器都遵循底层平台ABI。在你的情况下,平台是Windows,并且Windows平台ABI被遵守。

在这种情况下,对于这两个结构体的填充位于最后一个成员之后。第一个结构有一个额外的填充字节,第二个结构有三个额外的填充字节。

在struct最大类型具有尺寸4.这意味着,整体尺寸将是4。对于这两种结构的倍数,容纳结构体4的最小倍数为8

每个数据类型具有对齐属性。一个4字节的数据类型有4的对齐方式。一个2字节的数据类型有一个2的对齐方式。当一个对齐方式为4的类型被放置在从结构开始的4字节偏移处时被对齐。如果将对齐方式为2的类型放置在距结构起始位置2个字节的偏移处,则会进行对齐。等等。

成员被放置在尊重成员声明顺序和成员对齐属性的最小偏移处。

对于填充内部的结构的例子考虑这个结构

struct MyStruct 
{ 
    char c; 
    int i; 
}; 

c的对准是1,和的i对准为4。所以,c被放置在1个字节边界上,并i必须放置在4字节边界上。这意味着c将有偏移量0,那么会有3个填充字节,然后i将布置在偏移量为4.

+0

这意味着编译器推断,其中增加了额外的填充字节的地方,不是吗? – RyanAdamVeet

+0

是的,编译器决定如何布局结构。 –

+0

实际上,标准中存在一系列限制,基本上只剩下一种明智的做法。 –

1

编译器想要什么时候。如果重要,无论如何你都在做一些不可移植的东西,那么为什么它很重要?

+0

实际上,我为这个结构和一些保持结构的数据创建了一个BYTE数组。所以,总大小不会是结构本身,而是包括额外的数据缓冲区。变量BYTE bOffset存储数据偏移地址。我记得当我访问除结构成员以外的数据时会有什么问题 – RyanAdamVeet

0

看看这个:

typedef struct myTagDATA_PACK3 
{ 
    char c; 
    double d; 
    int i; 
}DATA_PACK3; 

它显示了24个字节。即: double:8个字节。 int:4个字节+(4个字节填充)= 8个字节。 char:1个字节+(7个字节填充)= 8个字节。


总计:24个字节。

+0

这个问题到底如何回答? –

+0

嘿,它不,但它仍然很酷! – thang

+0

@DavidHeffernan,这实际上是你的答案的例证。 –

1

尽管所有的答案都是由编译器决定的,但由于直到编译器,所以语言规范对布局有一些限制。这些限制适用于C中的所有结构,C++ 03中的“普通旧数据”(基本上意味着仅使用C中的特性)和C++ 11中的“标准布局”结构(允许具有构造函数和析构函数)。这些限制是:

  • (Reinterpret-)将结构指针转换为第一个成员的类型会生成第一个成员(C++ 11§9.2/ 20)的有效指针。这意味着在第一个成员之前不能填充。
  • 如果联合中的两个结构具有相同的初始部分(相同顺序中的同一类型的成员),并且通过其中一个联合初始化联合,则可以通过其他联合来访问这些初始成员(C++ 11§ 9.2/19)。这意味着成员偏移量可能仅取决于之前声明的成员。

对标准布局的限制很重要。对于具有基类或虚拟成员的类都不适用。

现在,当不想浪费内存的时候,这实际上只剩下一种实用算法,因此所有编译器都使用这种算法。这并不意味着所有的编译器都会为相同的输入生成相同的布局,因为不同平台之间各种基本类型的大小和对齐要求不同。该算法是:

  • 铺陈所述第一构件在偏移0
  • 铺陈每个下列构件在第一个可用的由它的所需的对准偏移整除。
  • 将结构的大小舍入到任何成员的最大对齐的下一个倍数。
  • 该结构的对齐要求是任何成员的最大对齐。

(我几乎可以肯定MSDN的MSVC++描述了这个地方,但不能很快找到它)

+0

+1好挖:第 – thang