Hi I'm new to C++ and I'm trying to write data from structure into binary file and then read the file and store the data back in the structure. Here is what I've done so far:
#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;
}
When I compile it everything works as it should. The data is displayed correctly and when I press a button to pass the system("pause") BOOM Access violation. What am I doing wrong?
You're effectively double-deleting your strings. A string is not plain-old data, you can't really just write it to a file and read from it, it's a dynamically allocated array of chars that is managed by the object. ~string()
will free the memory that it owns.
When you byte-wise copy the string
s (which you're effectively doing), you have two objects that both think they own the same data - and so when they go out of scope, they both try to free it. Hence, BOOM. You can achieve the same thing here:
{
std::string test = "hi";
std::string t2;
memcpy(&t2, &test, sizeof(std::string));
} // <-- death
If you want to read in binary data like this, you have to use POD types. Something like a char name[30]
will do.