简体   繁体   English

将struct写入文件时,写入了太多字节

[英]When writing struct to a file too many bytes are written

I'm trying to write a simple TGA image file saver as a learning exercise in C++. 我正在尝试编写一个简单的TGA图像文件保护程序,作为C ++中的学习练习。 I'm basing my code on an example TGA loader that declares a struct for the header and then uses fread() to load the entire header in one go. 我将代码基于示例TGA加载器,该加载器声明了标头的结构,然后使用fread()一次性加载了整个标头。

My program isn't working right now, and it seems like there are two extra bytes being written to the file. 我的程序目前无法正常工作,似乎有两个额外的字节正在写入文件。 I printed the sizeof my struct and it's two bytes too large (20 instead of the correct 18). 我打印了我的结构的大小,它的两个字节太大(20个字节,而不是正确的18个字节)。 After a little reading I think the problem is related to data alignment and padding (I'm not very familiar with how structs get stored). 稍作阅读后,我认为问题与数据对齐和填充有关(我对结构的存储方式不是很熟悉)。

My question is what's a good solution for this? 我的问题是对此有什么好的解决方案? I guess I could write the struct's components byte-by-byte, instead of using fwrite() to write the entire struct at once, which is what I'm going now. 我想我可以逐字节地编写该结构的组件,而不是使用fwrite()一次写入整个结构,这就是我现在要做的。 I assumed that if it worked when loading the header, it would also work when writing it. 我假设如果在加载标头时可以使用,那么在编写标头时也可以使用。 Was my assumption incorrect? 我的假设不正确吗?

Compilers are allowed to, and frequently do, insert padding bytes into structures so that fields are aligned on appropriate memory addresses. 允许编译器经常将填充字节插入结构中,以便字段在适当的存储器地址上对齐。

The simplest solution is to instruct the compiler to "pack" the structure, which means to not insert any padding bytes. 最简单的解决方案是指示编译器“打包”该结构,这意味着不要插入任何填充字节。 However this will make data access to the structure slower, and the means of doing it are compiler-dependent. 但是,这将使对结构的数据访问变慢,并且实现该方法的方式取决于编译器。 If you want to be portable and efficient, the only way to go is writing the fields individually. 如果您想变得可移植且高效,那么唯一的方法就是分别编写字段。

It did not work even when loading it. 即使加载它也不起作用。 You have a couple of options: 您有两种选择:

  1. Use compiler specific directives (#pragma packed, etc.) to force your structure to be 18 bytes. 使用编译器特定的指令(打包#pragma等)将结构强制为18个字节。

  2. Write the code more portable by using offsets and pointers to get/set the buffer fields. 通过使用偏移量和指针来获取/设置缓冲区字段,从而编写出更具移植性的代码。

Elements of a struct are generally arranged on 4byte boundaries. 结构的元素通常排列在4个字节的边界上。

if you have shorts, or chars in your struct, the struct is larger than the sum of the individual element sizes. 如果您的结构中有短裤或字符,则该结构大于各个元素大小的总和。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM