在《Unix 环境中的高级编程》一书中,有一部分(第 8.14 章,第 251 页)作者向我们展示了“acct”结构(用于存储会计记录信息)的定义。然后,他展示了一个程序,在该程序中,他将文件中的会计数据读取到结构中(其关键部分是):
fread (&acdata, sizeof(acdata), 1, fp)
我遇到的麻烦是,我听说 C 编译器有时会重新排列内存中结构的元素,以便更好地利用空间(由于对齐问题)。因此,如果此代码只是获取文件的所有内容并将其粘贴到 acdata 中(并且文件的内容被排列为与结构定义中指定的顺序匹配),并且结构的某些元素已被移动,那么如果我在代码中引用它们,我可能不会得到我所期望的结果(因为文件中的数据没有像结构在内存中那样重新排列)。
我错过了什么(因为从我得到的信息来看,这似乎不可靠)?
感谢您的帮助(如果我在程序上做错了什么,我很抱歉 - 这是我第一次发帖)
Worry!
你对这个问题的担心和关注是对的。这是一个令人烦恼的问题,当您将源代码转移到另一台具有不同(甚至略有不同)架构的机器时,并且可能具有不同的操作系统或不同的编译器时,经常会发生这种情况;在那里编译你的程序;并期望你的结构保持完整fwrite( )
and fread( )
。或者,当您向结构中添加 1 字节变量时,重新编译并向所有朋友发送二进制文件。由于某种神秘的原因,你的程序不再在他们的机器上运行。
有时它会起作用(偶然),但你却从未注意到这个问题;有时它不起作用,你会拔掉头发几天。
该问题与结构成员的重新排列无关。编译器不这样做。它也与优化无关。
问题是字节对齐,下面提到的维基百科文章告诉您如何修复结构,以便它们始终正确对齐。它是总是个好主意要注意字节对齐。否则你的程序不可移植。而且,更糟糕的是,您在 x86-64 上精心编译并分发给所有客户的程序突然无法在他们的 32 位计算机上运行。
同样重要的是:也要注意结构成员的长度和对齐方式。
有一个不错的维基百科文章 http://en.wikipedia.org/wiki/Data_structure_alignment这解释了细节。这是一本非常值得一读的书。
我会对完成这项工作的特定于编译器的编译指示保持警惕,但只是针对该编译器。如果您在代码中添加了编译指示,那么您的程序就不再是 C 语言了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)