c ++ munmap_chunk():指针无效:

时间:2018-03-15 04:28:13

标签: c++

我试图读取和写入二进制文件,但它主要工作

在主病例中返回0时获取munmap_chunk():无效指针:错误

在程序关闭时获取内存转储和堆栈跟踪

https://imgur.com/a/CSBg8

这是内存转储和堆栈跟踪的屏幕截图,我不知道如何阅读

#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;
}

1 个答案:

答案 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)是一个固定的编译时值,它是readwrite函数中的第三个参数。运行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等库。