我可以在64位机器上制作这种结构的最小尺寸是多少?

typedef struct node{ char one; char two; struct node *next; } nodea; 

我在考虑编译器填充方面,有什么方法可以使sizeof(nodea)小于16?

您可以使用#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 + 1 + 8 = 10个字节。 如果指针必须对齐,则为16个字节。 如果你把指针放在第一个并且接下来是字符,那么就是10个字节,但是当你创建这些结构的数组时,对齐要求仍然可以使它成为16。

假设底层硬件没有任何特定的对齐要求,则可以将其打包为10个字节。 请注意,一旦开始打包,就会让可移植性落空。

如何影响打包取决于您的编译器,但大多数编译器,包括gcc ,支持#pragma pack类型指令。

这取决于编译器。 通常,您可以控制结构字段/变量的对齐方式。 例如,使用gcc可以使用

 typedef struct __attribute__ ((packed)) node { char one; char two; struct node *next; } nodea; 

在64位平台上为sizeof(nodea)获得10。

在struct上使用packed也意味着编译器无法对数据结构进行重新排序,在某些平台上,打包可能会大幅降低性能。 有些处理器无法获得未对齐的字,因此如果代码将在该平台上编译,编译器将被强制获取每个字节的单词并将所有内容移位到正确的位置,这绝对是您不想要的。 特别是不在链表上,因为这会使你的列表真的真的很慢访问…即使cpu支持未对齐获取CPU需要额外的周期来从内存中的2个地址读取并再次连接它们。

这就是为什么你必须看看如何帮助编译器。 您可能希望struct是字对齐的,因此可以使用一条读取指令始终读取下一个节点的地址。 这意味着对于64位架构,您可能希望将下一个节点的指针置于顶部,以便始终对齐,接下来您要确保如果在数组中使用struct,则struct node *的地址将总是对齐,所以你需要确保你的最终结构大小是8字节的倍数。 这意味着您可以添加6个元素,或者您可以选择更大的数据类型。

这意味着你会得到这样的东西:

 typedef struct __attribute__((packed)) node { struct node *next; char data[8]; } nodea; typedef struct __attribute__((packed)) node { struct node *next; uint16_t data[4]; } nodea; typedef struct __attribute__((packed)) node { struct node *next; uint32_t data[2]; } nodea; 

等等