简体   繁体   English

关于数据对齐的困惑

[英]Confusion about data alignment

suppose a struct defined like this: 假设这样定义一个结构:

struct S{
    char a[3];
    char b[3];
    char c[3];
};

then what will be the output of printf("%d", sizeof(S)) ? 那么printf(“%d”,sizeof(S))的输出是什么? On My compiler of Vc++ 2008 expression, the output is 9. And I got confused... I suppose the result be 12, but it is not. 在我的Vc ++ 2008表达式的编译器上,输出为9。我很困惑……我想结果是12,但不是。 Shouldn't the compiler align the structure to 4 or 8 ? 编译器是否应该将结构对齐为4或8?

The value of the sizeof -expression is implementation-dependent; sizeof -expression的值与实现有关; the only thing guaranteed by the C++ standard is that it must be at least nine since you're storing nine char 's in the struct . C ++标准唯一保证的是,它必须至少为9,因为在struct存储了9个char

The new C++11 standard has an alignas keyword, but this may not be implemented in VC++08. 新的C ++ 11标准具有alignas关键字,但是在VC ++ 08中可能未实现。 Check your compiler's manual (see eg __declspec(align(#)) ). 检查您的编译器手册(例如,参见__declspec(align(#)) )。

S中没有什么可以迫使其任何成员(按字节)对齐,因此编译器根本不需要添加任何填充。

The typical requirement that each member be aligned only requires that the structure itself be aligned to the largest member type. 每个成员对齐的典型要求仅要求结构本身与最大成员类型对齐。 Since all member types are char , the alignment is 1 , so there's no need for padding. 由于所有成员类型均为char ,对齐方式为1 ,因此无需填充。 (For arrays, the base type (all extents removed) is what counts.) (对于数组,最重要的是基本类型(删除所有扩展区)。)

Think about making an array of your structure: You'll want all the members of all the elements of that array to be aligned. 考虑构造一个结构数组:您希望该数组所有元素的所有成员对齐。 But in your case that's just one large array of chars, so there's no need for padding. 但是在您的情况下,这只是一个大字符数组,因此无需填充。

As an example, suppose that on your platform sizeof(short) == 2 and that alignment equals size, and consider struct X { char a; short b; char c; }; 例如,假设在您的平台上sizeof(short) == 2且对齐方式等于大小,并考虑struct X { char a; short b; char c; }; struct X { char a; short b; char c; }; . Then there's one byte internal padding between a and b to align b correctly, but also one byte terminal padding after c so that the entire struct has a size that's a multiple of 2 , the largest member size. 然后在ab之间有一个字节的内部填充以正确对齐b ,但在c之后也有一个字节的终端填充,以便整个结构的大小是最大成员大小2的倍数。 That way, when you have an array X arr[10] , all the elements of arr will be properly aligned individually. 这样,当您拥有数组X arr[10]arr所有元素将分别正确对齐。

First, the alignment is implementation dependent, so it will depend on the compiler. 首先,对齐方式取决于实现,因此它将取决于编译器。

Now, remember that for a statically allocated array, the size need not be stored (the standard does not require it is), therefore it is usual for the alignment of an array to be the alignment of its elements. 现在,请记住,对于静态分配的数组,不需要存储大小(标准并不需要存储大小),因此通常将数组的对齐方式为其元素的对齐方式。

Here, char[3] thus has an alignment of 1 , and they are perfectly packed. 因此,这里的char[3]的对齐方式为1 ,并且它们被完美包装。

There is a compiler switch, /Zp, that allows you to set the default struct member alignment. 有一个编译器开关/ Zp,它允许您设置默认的结构成员对齐方式。 There are also some other methods for specifying alignment in the c language. 还有一些其他方法可以用c语言指定对齐方式。

Check out this MSDN post for details: 查看此MSDN帖子以了解详细信息:

http://msdn.microsoft.com/en-us/library/xh3e3fd0(v=vs.80).aspx http://msdn.microsoft.com/zh-CN/library/xh3e3fd0(v=vs.80).aspx

Maybe your compiler is using one of these settings? 也许您的编译器正在使用这些设置之一?

The compiler is given fairly wide latitude about how its aligns data. 编译器在如何对齐数据方面具有相当宽的自由度。 As a practical matter, however, the alignment of a datum will not exceed its size. 但是,实际上,基准的对齐不会超过其大小。 That is, char s must be byte-aligned, while int s and long s are often four-byte aligned. 也就是说, char必须是字节对齐的,而intlong常常是四字节对齐的。

Additionally, struct s are aligned to the strictest alignment requirement of their members. 另外,将struct对齐为其成员的最严格的对齐要求。

So, in your example, the strictest internal alignment requirement is 1-byte aligned, so the struct is 1-byte aligned. 因此,在您的示例中,最严格的内部对齐要求是1字节对齐,因此结构是1字节对齐。 This means that it requires no padding. 这意味着它不需要填充。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM