I'm reading a char array from a binary file using std::ifstream, then reinterpreting the char array into a pointer to my struct then making this a unique_ptr. Everything works well except when the unique_ptr goes out of scope I get a read access violation.
Am I going about this all wrong? I'm not sure why the error is occurring. I only have one unique_ptr on that data.
I've included the very basic version of the code to produce the error.
struct mystruct {
int val = 0;
double val2 = 5.6;
std::string string = "test";
};
int main()
{
//brackets here just to encapsulate the scope for this example
{
//try to open the stream for reading
std::ifstream stream;
stream.open("test.bin", std::ios::binary | std::ios::in);
char* buffer = new char[sizeof(mystruct)];
stream.read(buffer, sizeof(mystruct));
mystruct * pointer = reinterpret_cast<mystruct*>(buffer);
std::unique_ptr<mystruct> obj = std::unique_ptr<mystruct>(pointer);
//ha no problem reading the struct data
std::cout << "read back: " << obj->string << endl;
stream.close();
}
//obj goes out of scope and throws a read access violation
}
I expect the unique_ptr to just delete the object and no error should be thrown
**********EDIT********************
Thanks for the comments and answers - basically from your help I produced the code that I was trying to do so have listed it here in case it helps anyone else.
Main Points were:
* std::string is not recommended in struct if reading and writing from binary because std::string has unknown number of bytes.
* needed to create the object in memory before assigning the pointer to it - std::make_unique() was suitable for this.
struct mystruct {
int val1 = 0;
double val2 = 5.6;
char somestring[10] = "string";
};
int main()
{
//brackets here just to encapsulate the scope for this example
{
//try to open the stream for reading
std::ifstream stream;
stream.open("test.bin", std::ios::binary | std::ios::in);
//hold the results in a vector
auto results = std::vector<std::unique_ptr<mystruct>>();
//read a vectory or mystructs from the binary file
while (!stream.eof())
{
//create the object - NOTE: make_unique initialises my struct
std::unique_ptr<mystruct> obj = std::make_unique<mystruct>();
//read from binary file into obj
if (!stream.read(reinterpret_cast<char*>(obj.get()), sizeof mystruct))
break;
//add the obj to th vector
results.push_back(std::move(obj));
}
stream.close();
for (auto& val : results)
{
cout << "read back: " << val->somestring << endl;
}
}
}