【问题标题】:improving memory alignment of a structure on 32 bit machine改进 32 位机器上结构的内存对齐
【发布时间】:2013-10-29 11:20:45
【问题描述】:

更正下面那个不好的结构对齐方式。

typedef struct{ 
char *string; // 4 byte (type of address int)

char temp; // 1 byte

short pick; // 2 byte

char temp2; // 1 byte

}hello;
  • 字符串 = 4
  • temp + pick + temp2(offset 7) = 1+2+1

给出的答案,良好的对齐是

char *string; // 4 byte (type of address int)

short pick; // 2 byte

char temp; // 1 byte

char temp2; // 1 byte
  • 字符串 = 4
  • pick + temp + temp2(offset 7) = 2+1+1

无法理解 temp2 应位于偏移量 7 而不是 8 的原因。如何?请帮忙

【问题讨论】:

  • 您在这里指的是哪个问题和哪个答案?你指的平台是什么? char* 是 4 字节(32 位)或 8 字节(64 位),所以不确定你何时说 2 字节
  • 刚刚编辑了帖子,忽略了问答部分,把它当作32位平台..
  • 还是错了:在 32 位平台上,指针是 4 字节,int 总是 4 字节(不管是 32 位还是 64 位)。 Short 是 2 个字节,char 是 1 个字节,尝试通过以下方式读取:msdn.microsoft.com/en-us/library/ms253949(v=vs.80).aspx
  • @Sarang: int 在 64 位平台 (ILP64) 上可以是 64 位。
  • 感谢您的参考,您是正确的地址是 int 并且是 4 字节,但在两种情况下 temp2 的偏移量仍然保持不变(7)..

标签: c memory padding


【解决方案1】:
+---+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+---+---+---+---+---+---+---+---+
|    string     | pick  | t1| t2|
+---+---+---+---+---+---+---+---+

使用t1 代表tempt2 代表temp2,这是修改后的布局。 t2 的偏移量为 7。

对于 n 字节数量与 n 字节对齐的系统上的原始结构,布局将是:

+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B |
+---+---+---+---+---+---+---+---+---+---+---+---+
|    string     | t1|pad| pick  | t2|pad|pad|pad|
+---+---+---+---+---+---+---+---+---+---+---+---+

那是因为4字节的指针需要4字节对齐,所以结构的数组需要每个成员都是4字节的倍数。

因此,在原始结构中,t2 的偏移量应该是 8,而不是 7。

【讨论】:

  • 所以,问题和答案中t2的偏移量都是7,这意味着在回答我时给出的解释是错误的。所问的结构记忆已经对齐。谢谢!
  • 谢谢乔纳森,我可以理解,但我仍然无法理解为什么短类型(即选择)需要从偶数地址开始,如果内存对齐需要为 4 个字节。或者只是为什么我需要在 t1 和 pick 之间放置一个垫子?
  • 因为 pick 是一个 2 字节的变量,所以它应该从 2 字节对齐的边界开始。它可能从上图中的插槽 4 开始。但是 t1 在那里并且占据了一个偶数字节。现在,如果你有一个 1 字节的变量,它可以代替 5(填充),但它是 2 字节,所以它应该从偶数地址开始。这可能会帮助stackoverflow.com/a/16456405/986760
  • @fayyazki,我非常感谢您为我解释整个想法所付出的努力..但我害怕重新构建我的问题,即..如果 32 位处理器要读取四个字节如果选择从第 5 个或第 6 个字节开始,那么它有什么不同呢?或者换句话说,如果 4 字节边界已经存在,为什么还需要 2 字节边界? 2 字节边界如何帮助 32 位处理器?
  • 这是指令集的问题,在哪里容易将值加载到寄存器中的正确位置。如果 2 字节整数位于 4 字节寄存器的中间 2 字节,则没有多大帮助;你必须改变它才能使用它。这是为了避免芯片强加限制的那种事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-06
  • 2016-04-10
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多