【问题标题】:Reading from a binary file gives me access violation从二进制文件中读取会导致访问冲突
【发布时间】:2015-02-18 23:40:49
【问题描述】:

您好,我是 C++ 新手,我正在尝试将数据从结构写入二进制文件,然后读取文件并将数据存储回结构中。这是我到目前为止所做的:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

struct Data{
    string name;
    int points[6];
};

int main(){
    Data stream[20];
    Data my[20];

    for (int i = 0; i < 20; i++){
        stream[i].name = "name" + to_string(i);
        for (int j = 0; j < 6; j++)
        {
            stream[i].points[j] = j + i;
        }
    }

    ofstream writer("data.dat", ios::binary | ios::trunc);
    if (writer.is_open()){
        writer.write((char *)stream, sizeof(stream));
        writer.close();
    }
    else cout << "Error opening file.\n";

    ifstream reader("data.dat", ios::binary);
    if (reader.is_open()){
        reader.read((char *)my, sizeof(my));
        reader.close();
    }
    else cout << "Error opening file.\n";

    for (int i = 0; i < 20; i++){
        cout << my[i].name;
        for (int j = 0; j < 6; j++)
        {
            cout << " " << my[i].points[j];
        }
        cout << endl;
    }

    system("pause");
    return 0;
}

当我编译它时,一切正常。数据显示正确,当我按下按钮传递系统(“暂停”)BOOM 访问冲突时。我做错了什么?

【问题讨论】:

  • 您希望sizeof(my) 是什么?当您打印sizeof(my) 时,它实际上是什么?见stackoverflow.com/questions/3629301/c-sizeof
  • 你不能在这样的二进制文件中输入和输出std::string。您需要形成一个原生类型的普通旧数据 protocol 来编写该文件,然后坚持下去。

标签: c++ struct ifstream


【解决方案1】:

您实际上是在双重删除您的字符串。字符串不是普通的旧数据,您实际上不能将其写入文件并从中读取,它是由对象管理的动态分配的字符数组。 ~string() 将释放它拥有的内存。

当您按字节复制strings(您实际上正在这样做)时,您有两个对象都认为它们拥有相同的数据 - 因此当它们超出范围时,它们都会尝试释放它。因此,繁荣。您可以在这里实现相同的目标:

{
    std::string test = "hi";
    std::string t2;
    memcpy(&t2, &test, sizeof(std::string));
} // <-- death

如果你想像这样读入二进制数据,你必须使用 POD 类型。像char name[30] 这样的东西就可以了。

【讨论】:

    猜你喜欢
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多