尝试将数字写入二进制文件时引发异常

Exception is thrown when trying to write a number to a binary file

本文关键字:异常 二进制文件 数字      更新时间:2023-10-16

我一直在尝试用c ++创建自己的二进制文件。我正在做的是我定义了一个结构,它实际上与 dds 标头的结构相同。所以我要做的是首先在二进制文件中写入一个小版本号,看看我处于哪个阶段,然后将整个结构写入文件,最后我将一个简单的文本字符串写入文件。 但是,当我尝试将版本号写入文件时,会引发如下异常:"在 TestApplication7 中0x0F377236 (msvcp140d.dll .exe 引发异常: 0xC0000005:访问冲突读取位置0x499602DB。

所以基本上我正在做的是我在 cpp 文件的顶部定义一个版本号,如下所示:

#define VERSION_NR 0x499602DB

然后我只是简单地尝试将此数字写入二进制文件。

这是我的示例的代码:

void  MyFile::Save(std::string ddsPath, MyFile::FileHeader header, const std::string texturePath) {
header.PathLen = texturePath.length();
const char* buffer{reinterpret_cast<const char*>(&texturePath)};
const char* version{reinterpret_cast<const char*>(VERSION_NR)};
std::ofstream output(ddsPath, std::ios::binary);
output.write(version, sizeof(VERSION_NR)); //Here is where the exception is thrown
ext->WriteStruct(output, header); //Writing the hole header to the file
output << texturePath; //Outputting a simple text to the file
}

所以它是这样的代码:

output.write(version, sizeof(VERSION_NR));

这导致异常被抛出,我不知道我做错了什么,因为我对 c++ 编程非常陌生。我确实尝试在"保存"方法中创建 const DWORD 而不是使用宏,但我仍然得到相同的异常。 我不知道这是否有帮助,除了消息"访问违规读取位置0x499602DB"与我的宏的值相同"位置"之外,其他什么都没有。

如果有人可以帮助我,或者只是为我指出正确的方向,我将不胜感激。 谢谢!

如果我们去掉宏和许多其他不相关的代码,我们会得到:

int version = 0x499602DB;
const char* ch = reinterpret_cast<const char*>(version);
std::ofstream output("out.bin", std::ios::binary);
output.write(ch, sizeof(version));

您是正确的,您的版本值出现在错误消息中的事实是一个线索。第二行将整数值转换为地址0x499602DB的字符指针。由于此地址在尝试访问时不指向有效的内存output.write地址,因此 OS 不允许该操作,并引发和访问冲突。

正确的代码是:

int version = 0x499602DB;
const char* ch = reinterpret_cast<const char*>(&version);
std::ofstream output("out.bin", std::ios::binary);
output.write(ch, sizeof(version));

或者,当您无论如何都想编写字符串时,请一起避免所有强制转换:

const char version[4] = {'xDB','x02','x96','x49'};
std::ofstream output("out.bin", std::ios::binary);
output.write(version, sizeof(version));

另请注意,一旦我们修复了此崩溃,以下内容也是不正确的:

const char* buffer{reinterpret_cast<const char*>(&texturePath)};

并且应该简单地:

const char* buffer = texturePath.c_str();

texturePath是一个std::string对象,指向它的指针不能转换为char*c_str()方法返回一个const char*指针,然后你可以传递给std::ofstream::write,或者只是像你已经做的那样使用output << texturePath,只是删除buffer变量。

VERSION_NR不是变量,因此char*指向随机内存。 不要使用宏,创建一个变量,获取一个指针,就像你对其他数据所做的那样。