【问题标题】:c++ munmap_chunk(): invalid pointer:c++ munmap_chunk():无效指针:
【发布时间】:2018-08-23 19:12:17
【问题描述】:

我正在尝试读取和写入二进制文件,但它大部分都可以工作

在 main 中返回 0 时会得到 munmap_chunk(): invalid pointer: error

程序关闭时将获得内存转储和堆栈跟踪

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

【问题讨论】:

  • filestream.read(reinterpret_cast &lt;char *&gt; (&amp;playerData), sizeof(playerData)); -- 这条线永远行不通。 playerData 是非 POD 类型,因此您无法以这种方式读取或写入这些类型。了解正确的对象序列化。
  • More reading on object serialization。我几乎想把它作为一个副本关闭,因为我看到很多问题都有相同的错误——试图对非 POD 类型进行错误的二进制读取和写入。
  • 我看不懂那个帖子,好像在告诉我在结构中写一个静态函数但我不知道如何使用它
  • Read the accepted answer here。您的代码将不起作用,期间。如果您不明白,请阅读我的答案。

标签: c++


【解决方案1】:

您的 player 结构包含 std::string,因此该类型与 C 布局不兼容。

因此使用如下函数:

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 布局兼容,并且可以使用您的二进制文件读取/写入技术进行读取和写入

2) 将字符串数据正确序列化到文件中。您可以重载operator &gt;&gt;operator &lt;&lt; 来读取/写入字符串数据,或者使用Boost::Serialize 等库。

【讨论】:

    猜你喜欢
    • 2020-08-04
    • 2016-03-16
    • 2016-08-08
    • 2014-05-14
    • 1970-01-01
    • 2020-08-04
    • 2020-09-05
    • 2012-07-19
    • 1970-01-01
    相关资源
    最近更新 更多