在"Unix环境中的高级编程"一书中,有一部分(第8.14页,第251页),其中作者向我们展示了"acct"结构的定义(用于存储会计记录信息).然后,他显示了一个程序,在该程序中,他将会计数据从文件读入结构(其中的关键部分):
fread (&acdata, sizeof(acdata), 1, fp)
Run Code Online (Sandbox Code Playgroud)
我遇到的麻烦是我听说C编译器有时会在内存中重新排列结构元素,以便更好地利用空间(由于对齐问题).因此,如果此代码只是获取文件的所有内容并将其粘贴到acdata中(并且文件的内容被排列为与结构定义中指定的顺序相匹配),如果某些元素的元素已被移动,那么如果我在代码中引用它们,我可能无法得到我所期望的(因为文件中的数据没有像结构在内存中那样重新排列).
我错过了什么(因为从我得到的东西看起来不太可靠)?
谢谢你的帮助(道歉,如果我在程序上做错了 - 这是我第一次发帖)
你担心这个问题是正确的,并注意它.这是一个令人烦恼的问题,并且经常发生在您将源代码传输到另一台机器时,它具有不同的 - 甚至略有不同的 - 架构,并且可能具有不同的操作系统或可能是不同的编译器; 在那里编译你的程序; 并希望你的结构在fwrite( )和之上保持完整fread( ).或者,当您向结构中添加1字节变量时,重新编译,并将二进制文件发送给您的所有朋友.出于某种神秘的原因,你的程序不再适用于他们的机器了.
有时候它会起作用(偶然),你从来没有注意到这个问题; 有时它不起作用,你把头发拉了几天.
isssue与struct成员的重新排列无关.编译器不这样做.它与优化无关.
问题是字节对齐,下面提到的维基百科文章告诉您如何修复结构,以便它们始终正确对齐.它总是一个好主意,要注意字节对齐.否则您的程序不可移植.而且,更糟糕的是,您在whiz-bang x86-64上仔细编译并且突然分发给所有客户的程序将无法在其32位计算机上运行.
同样重要的是:注意结构成员的长度和对齐.
有一篇很好的维基百科文章解释了细节.这是一个非常值得一读的内容.
我会警惕编译器特定的pragma来完成这项工作,但仅限于该编译器.如果你在代码中添加了一个pragma,那么你的程序就不再是C了.
| 归档时间: |
|
| 查看次数: |
2187 次 |
| 最近记录: |