我在C中读到了有关结构填充的内容: http://bytes.com/topic/c/answers/543879-what-structure-padding 并且在文章之后写了这段代码,应该打印出'struct pad'的大小,如16字节,'struct pad2'的大小应该是12.-我认为。 我使用gcc编译了这段代码,具有不同的优化级别,即使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;
}
答案 0 :(得分:4)
有两种技巧可以用来解决这个问题
使用指令#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
答案 1 :(得分:3)
你的结构每个都包含一个long
,你的平台显然需要在一个四字节的边界上。该结构必须至少与其最对齐的成员对齐,因此它必须是4字节对齐的,并且结构的大小必须是其对齐的倍数,以防它进入数组。
需要额外填充才能使long
对齐,因此4的最小倍数为16。
两条建议:
您可以按
计算字段l1
的偏移量
printf("Offset of field %s is %d\n", "l1", offsetof(struct pad, l1);
要获得offsetof
宏,您需要#include <stddef.h>
(感谢caf!)。
如果您想尽可能密集地打包数据,请使用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。我绝对不应该在午夜后回答这些问题。
答案 2 :(得分:1)
在PS3上,不要猜。使用__attribute__((aligned (16)))
或类似内容。它不仅保证结构的开始将在适当的边界上对齐(如果是全局的或静态的),它还将结构填充到指定对齐的倍数。
答案 3 :(得分:1)
您的代码未显示您的想法,因为P1和P2都被定义为struct pad的实例。从未使用过struct pad2。
如果我更改了P2的定义以使其成为struct pad2,那么gcc确实决定将其设置为12。
答案 4 :(得分:1)
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
P1和P2具有相同类型的“struct pad”,也许你想对P2使用“struct pad2”。
答案 5 :(得分:1)
所有CPU都希望内置数据类型(如int,float,char,double)以其自然边界存储在内存中,其长度为地址。因此,可以更快地访问内存中的数据。 。 例如, 如果声明了int,它应该在内存中以4的地址出现,如
int的大小是4个字节。
同样,对于double,它以8的倍数驻留在内存中。
如果内存正确对齐,CPU可以更快地运行并高效工作。
对于以下示例,我们假设:
Sizeof(int)= 4字节
Sizeof(float)= 4字节
Sizeof(char)= 1个字节
查找有关BoundsCheck
的详细信息