我试图读取和写入二进制文件,但它主要工作
在主病例中返回0时获取munmap_chunk():无效指针:错误
在程序关闭时获取内存转储和堆栈跟踪
这是内存转储和堆栈跟踪的屏幕截图,我不知道如何阅读
#include <fstream>
#include <iostream>
using namespace std;
struct player{
string name;
};
bool WriteTest(player playerData){
// Create our objects.
fstream filestream;
//attempt to open file and then read first player
filestream.open ("file.bin", ios::binary | ios::out);
filestream.write(reinterpret_cast <char *> (&playerData),
sizeof(playerData));
if(filestream.fail()){
//create file if there is no file
cout << "write open failed" << endl;
filestream.close();
return false;
}
filestream.close();
cout << "write sucsess" << endl;
return true;
}
player ReadTest(){
player playerData;
// Create our objects.
fstream filestream;
//attempt to open file and then read first player
filestream.open ("file.bin", ios::binary | ios::in);
filestream.read(reinterpret_cast <char *> (&playerData),
sizeof(playerData));
if(filestream.fail()){
//create file if there is no file
cout << "read open failed" << endl;
filestream.close();
return playerData;
}
filestream.close();
cout << "read sucsess" << endl;
return playerData;
}
void displayPlayerData(player playerData){
cout << " Name :" << playerData.name << endl;
}
int main(){
player source;
source.name = "bap";
displayPlayerData(source);
WriteTest(source);
getchar();
player playerData = ReadTest();
displayPlayerData(playerData);
return 0;
}
答案 0 :(得分:0)
您的player
结构包含std::string
,因此该类型不兼容C-layout。
因此使用如下函数:
filestream.write(reinterpret_cast <char *> (&playerData), sizeof(playerData));
和
filestream.read(reinterpret_cast <char *> (&playerData), sizeof(playerData));
无效。
std::string
包含指向字符缓冲区的指针(如果以这种方式实现字符串类,则将短字符串缓冲区放在一边),将std::string
直接写入文件将完全错过这些字符因为你只会写一个指针值。
此外,阅读playerData
不会使用数据初始化std::string
。相反,您只会使用从文件中读取的垃圾来破坏std::string
对象。这很可能是您的程序失败的原因 - 您正在尝试使用损坏的std::string
对象。
但是告诉我们为什么永远无法工作的标志是sizeof(player)
是一个固定的编译时值,它是read
和write
函数中的第三个参数。运行here时,sizeof(player)
为32.因此,您将始终读取/写入32个字节的数据。如果std::string name;
成员拥有1,000个字符怎么办?如何通过指定只读/写32个字节来读取/写入1,000个字符?那可能永远不会奏效。
处理此问题的正确方法是:
1)将std::string
成员更改为char
数组。然后player
类将与C-layout兼容,并且可以使用二进制文件读/写技术读取和写入
或
2)将字符串数据正确序列化到文件中。您可以重载operator >>
和operator <<
来读取/写入字符串数据,或使用Boost::Serialize等库。