题
我已经读过这个关于结构填充C:http://bytes.com/topic/c/answers/543879-what-structure-padding 和写这个代码之后,文章应该怎么打印出来大小的结构垫像16字节和大小的结构pad2'应该是12.-因为我认为。我编写这个代码与海湾合作委员会,与不同级别的优化,甚至sizeof()操作者给了我他们两个16字节。为什么是这?
这个信息是必要的,对我来说,因为的PS3机,那里的字节的边界和剥削的全dma转让是重要的:
#include <stdio.h>
#include <stdlib.h>
struct pad
{
char c1; // 1 byte
short s1; // 2 byte
short s2; // 2 byte
char c2; // 1 byte
long l1; // 4 byte
char c3; // 1 byte
};
struct pad2
{
long l1;
short s1;
short s2;
char c1;
char c2;
char c3;
};
int main(void)
{
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
return EXIT_SUCCESS;
}
解决方案
有两种技巧可以用来解决这个问题
-
使用指令#pragma pack(1)然后#pragma pack(pop) 例如:
#pragma pack(1) struct tight{ short element_1; int *element_2; }; #pragma pack(pop)
-
要在编译期间检查两个结构的大小是否相同,请使用此技巧
char voidstr[(sizeof(struct1)==sizeof(struct2)) - 1]; //it will return error at compile time if this fail
醇>
其他提示
你的结构,每个都包括 long
, 您的平台,显然需要应对一个四字节的边界。该结构必须至少作为对准作为其最盟成员,因此它已将4-byte结盟和结构的规模是一个多其准的情况下,进入阵列。
额外的填补所需要的 long
对准,并使最小的多的4个是16。
两片的建议:
你可以计算出抵消的领域
l1
通过printf("Offset of field %s is %d\n", "l1", offsetof(struct pad, l1);
得到的
offsetof
宏你会需要#include <stddef.h>
(谢谢你的咖啡馆!).如果你想要的数据,如人口密集的作为可能的使用
unsigned char[4]
而不是的long
和unsigned char[2]
而不是的short
, 和做算术转换。
编辑::的 sizeof(struct pad2)
是 12.你的代码中有一个错误;结构 P2
声明的类型 struct pad
.试试这个:
#define xx(T) printf("sizeof(" #T ") == %d\n", sizeof(T))
xx(struct pad);
xx(struct pad2);
P.S.我肯定应该停止试图回答这样的问题,午夜后。
在PS3上,不要猜。使用__attribute__((aligned (16)))
或类似的。它不仅保证结构的开始将在适当的边界上对齐(如果是全局的或静态的),它还将结构填充到指定对齐的倍数。
您的代码未显示您的想法,因为P1和P2都被定义为struct pad的实例。从未使用过struct pad2。
如果我更改了P2的定义以使其成为struct pad2,那么gcc确实决定将其设置为12。
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
P1和P2具有相同的类型<!> quot; struct pad <!> quot;也许你想用<!> quot; struct pad2 <!> quot;对于P2。
所有CPU都希望内置数据类型(如int,float,char,double)以其自然边界存储在内存中,位于其长度的地址。因此,可以通过结构填充来更快地访问内存中的数据。 例如, 如果声明了int,它应该在内存中以4的地址出现,如
int的大小是4个字节。
同样,对于double,它以8的倍数驻留在内存中。
如果内存正确对齐,CPU可以更快地运行并高效工作。
对于以下示例,我们假设:
Sizeof(int)= 4字节
Sizeof(float)= 4字节
Sizeof(char)= 1个字节
详细了解 BoundsCheck 一>