Visual Studio 2008 - 关于 C++ 中的结构填充
visual studio 2008 - Regarding structure padding in c++
我在项目中使用数据结构,在狭隘结构的上下文中,我对结构填充有疑问。首先看看下面给出的结构。我使用Visual Studio 2008编译器。
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 之后还是之前?
非常感谢您的所有回答。
标准未指定结构和类的对齐和填充。这完全取决于编译器。但是,所有健全的编译器都遵循底层平台 ABI。在您的情况下,平台是Windows,并且遵守Windows平台ABI。
在这种情况下,两个结构的填充都在最后一个成员之后。第一个结构有一个额外的填充字节,第二个结构有三个额外的填充字节。
结构中最大的类型大小为 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 布局。
想要的任何地方。 如果它很重要,无论如何你都在做一些不可移植的事情,那么为什么它很重要呢?
虽然所有说这取决于编译器的答案都是正确的,因为它取决于编译器,但语言规范对布局施加了一些限制。这些限制适用于 C 中的所有结构、C++03 中的"纯旧数据"(这基本上意味着只使用 C 中的功能)和 C++11 中的"标准布局"结构(允许具有构造函数和析构函数)。限制是:
- (
- 重新解释-)将指向结构的指针强制转换为第一个成员的类型,生成指向第一个成员的有效指针 (C++11 §9.2/20)。这意味着在第一个成员之前不能有填充。 如果联合中的两个结构具有相同的初始部分(相同类型的成员以
- 相同的顺序),并且联合通过其中一个进行初始化,则可以通过另一个结构访问这些初始成员 (C++11 §9.2/19)。这意味着成员偏移量可能仅取决于在其之前声明的成员。
对标准布局的限制很重要。对于具有基类或虚拟成员的类,两者都不成立。
现在,当与不浪费内存的愿望相结合时,这实际上只剩下一个实用的算法,因此所有编译器都使用它。这并不意味着所有编译器都会为相同的输入生成相同的布局,因为各种基元类型的大小和对齐要求因平台而异。算法为:
- 在偏移量 0 处布置第一个成员。
- 在第一个可用偏移处布置每个跟随成员,可由其所需的对齐方式整除。
- 将结构的大小舍入到任何成员的最大对齐方式的下一个倍数。
- 结构的对齐要求是任何杆件的最大对齐。
(我几乎可以肯定MSDN的MSVC++在某处描述了这一点,但无法快速找到它)
看看这个:
typedef struct myTagDATA_PACK3
{
char c;
double d;
int i;
}DATA_PACK3;
它显示 24 个字节。那是:双精度:8 字节。int : 4 字节 + (4 字节填充) = 8 字节。字符:1 字节 +(7 字节填充)= 8 字节。
总计:24 字节。
- 使用结构成员指针在C++中填充结构
- C++:使用缓冲区中的数据填充结构
- 在AAPCS(ARM ABI)下,C/C++结构填充的稳定性如何
- 我想直接在结构中插入,但没有一种方法可以正确避免填充问题
- 用二进制文件填充结构
- 哪些值存储在对齐的结构/类对象的填充字节中
- 使用初始化列表填充C++中的多维结构数组时出现问题
- sizeof 函数如何在带和不带位字段的结构上工作?(填充)
- 与STD :: BITSET的工会成员的结构填充
- 是否有任何环境会导致"int"结构填充?
- 如何在编译时计算c++11中的结构填充
- C++:OpenGL,glm和结构填充
- 关于结构填充
- 赛灵思微火焰结构填充/填料
- C++结构填充和字段打包
- C++ 用结构填充 2D 矢量
- VS 2008/2010中是否控制尾部结构填充?(#pragma包不够好)
- 64位计算机上的结构填充
- Visual Studio 2008 - 关于 C++ 中的结构填充
- 数据结构填充