C 结构填料

C 结构填料,c,structure,C,Structure,我试图理解为什么结构填充是memcmp无法比较结构的原因。 关于结构填充,我不明白的一点是。。。 为什么“短字符应该是2字节对齐的”或者“长字符应该是4字节对齐的”。我知道这与它们的大小有关,但为什么它们不能出现在任何字节边界上 或者换句话说“为什么0x10004566不是长变量的有效位置,而0x10004568是?”因为某些平台(即CPU)在物理上不支持“错误对齐”的内存访问。其他平台支持它们,但速度要慢得多 结构中的填充取决于编译器所做的选择,但它会做出这些选择,以满足代码所针对的CPU的特

我试图理解为什么结构填充是memcmp无法比较结构的原因。 关于结构填充,我不明白的一点是。。。 为什么“
短字符应该是2字节对齐的”
或者“
长字符应该是4字节对齐的”
。我知道这与它们的大小有关,但为什么它们不能出现在任何字节边界上

或者换句话说
“为什么0x10004566不是长变量的有效位置,而0x10004568是?”

因为某些平台(即CPU)在物理上不支持“错误对齐”的内存访问。其他平台支持它们,但速度要慢得多


结构中的填充取决于编译器所做的选择,但它会做出这些选择,以满足代码所针对的CPU的特定要求。

关于对齐,我能想到的唯一附加示例是数据传输,数据传输(取决于体系结构)例如,如果数据跨越边界,则可能需要2次传输才能接收数据,而不是1次。在优化程序速度时,内存对齐是一个非常重要的问题。C、 一般来说,作为一种非常强调速度的语言,喜欢执行一些规则,这些规则可能会使程序更快

对齐和未对齐内存访问的限制直接来自用于从内存获取数据的硬件,该硬件通常以与机器字大小相等的块获取数据。假设您想要访问存储在位置101的双字(4字节)。这意味着存储器控制器必须首先(可能)在位置100读取双字,然后在位置104再次读取双字,然后将来自位置101、102、103和104的各个字节拼接在一起。整个操作(假设)需要两个时钟周期

如果您想访问位置100处的双字,则不存在这样的问题,我提供的示例应该足够清楚地说明这一点

事实上,未对齐的数据访问是一个大问题,如果您试图使用SSE指令访问未对齐的数据,SSE指令(“对齐”版本,也有不这样做的“未对齐”版本)将导致一般保护故障


根据经验,在4字节边界上对齐4字节数据,在8字节边界上对齐8字节数据,依此类推,从来都不会有什么坏处。

如果从0x10004566开始一直朝着零的方向走,那么可以放置4个字节的第一个位置是0x00000002,从而“浪费”2个字节的内存(0x00000000和0x00000001字节)。这是有道理的。但是与添加填充(这种情况经常发生)相比,2字节的空间还不够小。它们一包8个,但你只想要7个。。。因此,您打开数据包并删除1。下次你再要7个。。。因此,你从之前取下剩下的1个,打开另一个包,取出2个。等等现在想象一下,你得到8个,然后扔掉1个。下一次,当你得到另一个8并且扔掉另一个时,…——字节比电池便宜:)因此,您的意思是,计算这种读取的确切位置所涉及的开销(如果不涉及填充)将很麻烦,并且需要很多周期。相反,您可以更喜欢使用填充(因为字节更便宜:)。。。只是确定我说的对。是的,这就是我的意思。读取4(或8,或16,…1024…)字节的对齐块对硬件来说更自然。