从二进制文件读取会导致访问冲突

时间:2014-12-20 01:42:36

标签: c++ struct ifstream

您好我是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;
}

当我编译它时,一切都按预期工作。数据显示正确,当我按下按钮传递系统时(&#34;暂停&#34;)BOOM访问冲突。我做错了什么?

1 个答案:

答案 0 :(得分:1)

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

当你按字节顺序复制string(你实际上正在做)时,你有两个对象都认为它们拥有相同的数据 - 所以当它们超出范围时,它们都会尝试释放它。因此,BOOM。你可以在这里做同样的事情:

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

如果要读取这样的二进制数据,则必须使用POD类型。像char name[30]这样的东西会。