typedef struct node{
char one;
char two;
struct node *next;
} nodea;
我在考虑编译器填充方面,有什么办法可以让sizeof(nodea)小于16吗?
答案 0 :(得分:5)
您可以使用#pragma pack
编译器指令http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs.80%29.aspx
#pragma pack(push)
#pragma pack(1)
typedef struct node {
char one;
char two;
struct node* next;
} nodea;
#pragma pack(pop)
答案 1 :(得分:5)
除非它是非常规的东西,否则它可以打包成1 + 1 + 8 = 10个字节。如果指针必须对齐,则为16个字节。如果你把指针放在第一个并且接下来是字符,那么就是10个字节,但是当你创建这些结构的数组时,对齐要求仍然可以使它成为16。
答案 2 :(得分:4)
如果打包它可以使它成为10个字节,假设底层硬件没有任何特定的对齐要求。请注意,一旦开始打包,您就会留下便携性。
如何影响打包取决于您的编译器,但大多数编译器,包括gcc,支持#pragma pack
类型指令。
答案 3 :(得分:1)
这取决于编译器。通常,您可以控制结构字段/变量的对齐方式。例如,使用gcc,您可以使用
typedef struct __attribute__ ((packed)) node {
char one;
char two;
struct node *next;
} nodea;
在64位平台上获得sizeof(nodea)
的10。
答案 4 :(得分:0)
在结构上使用packed也意味着编译器无法重新排序数据结构,在某些平台上打包可能会导致性能下降。有些处理器无法获得未对齐的字,因此如果代码将在该平台上编译,编译器将被强制获取每个字节的单词并将所有内容移位到正确的位置,这绝对是您不想要的。特别是不在链表上,因为这会使你的列表真的真的很慢访问...即使cpu支持未对齐获取CPU需要额外的周期来从内存中的2个地址读取并再次连接它们。 / p>
这就是为什么你必须看看如何帮助编译器。您可能希望struct是字对齐的,因此可以使用一条读取指令始终读取下一个节点的地址。这意味着对于64位架构,您可能希望将下一个节点的指针置于顶部,以便始终对齐,接下来您要确保如果您在数组中使用结构{{1}的地址将始终对齐,因此您需要确保最终的结构大小是8个字节的倍数。这意味着您可以添加6个元素,或者您可以选择更大的数据类型。
这意味着你会得到这样的东西:
struct node *
等。等等。