我正在使用 C++ 和 Visual Studio 2008。假设我有这样的结构:
struct StructOfInts
{
int a;
int b;
int c;
};
这应该像这样读取和写入:
void Read( std::istream& is, StructOfInts& myStruct )
{
is.read( (char*)&myStruct.a, sizeof myStruct.a );
is.read( (char*)&myStruct.b, sizeof myStruct.b );
is.read( (char*)&myStruct.c, sizeof myStruct.c );
}
void Write( std::ostream& os, StructOfInts& myStuct )
{
os.write( (char*)&myStruct, sizeof myStruct );
}
在读取或写入文件时,上述代码是否会导致某种内存损坏?我所说的内存损坏是指读入的值不正确。我正在尝试确定正在读入的 -1.#QNB 值的来源,并且想知道这是否可能是原因。 另外,如果我使用 pragma pack 打包结构会有什么不同吗?
最佳答案
是的,由于 struct
字段之间可能存在填充,您的代码可能导致读入无效值。让我们使用 struct StructOfInts 的示例,并想象编译器在字段之间插入一些填充,如下所示:
byte | 0 1 2 3 | 4 5 | 6 7 8 9 | 10 11 12 13
value | field a | padding | field b | field c
然后,当您将结构写入流时,您可能会得到类似的结果
byte | 0 1 2 3 | 4 5 | 6 7 8 9 | 10 11 12 13
char | \0 \0 \0 'a' | '?' '?' | \0 \0 \0 'b' | \0 \0 \0 'c'
如果字段(分别)包含值(int)'a'、(int)'b'、(int)'c'
。
然后当您读回这些值时,它看起来像
myStruct->a = int version of \0 \0 \0 'a'
myStruct->b = int version of '?' '?' \0 \0
myStruct->c = int version of \0 'b' \0 \0
这显然不是你想要的。
在搜索了#pragma pack
之后,看起来它会对这种情况有所帮助。编译器不会插入填充(尽管它是实现定义的...),因此这些值(很可能)会被正确读取和写入。
此外,另一件事:如果您在一个系统(计算机/操作系统/编译器)上进行写入,然后在另一个系统中读取数据,那么字节序问题也可能会导致问题。
关于C++ 按字段读取结构并将结构直接写入流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17454201/