Solved Save struct like binary file
-
Hi,
I have a some problem with crash the application while I try loading the structure from binary file.
My structure deninition:struct Parameters{
int ID = 0;
QString name = "Section";
int temperature_expected = 0;
};I create binary file :
Parameters parameters; QFile file(filename); if(!file.open(QFile::WriteOnly)){ qDebug()<<"Cant open file"; return; } file.write((char*)¶meters, sizeof(parameters)); file.flush(); file.close();
But when i try load file, the application is crashed
QFile file(path); if (!file.open(QIODevice::ReadOnly)){ qDebug()<<"Cant open load file"; return false; } QByteArray bytes = file.readAll(); if(bytes.size() != sizeof(Parameters)){ return false; } Parameters* parameters = reinterpret_cast<Parameters*>(bytes.data()); return true;
anyone know what could be wrong?
-
Parameters* parameters = reinterpret_cast<Parameters*>(bytes.data());
You have left
parameters
pointing into thedata()
of aQByteArray
which has gone out of scope. When you later (presumably) try to read from the content you get rubbish back, including theQString name
. If you try to write into*parameters
havoc ensues. And you can's storeQString
s to file like this anyway.Do you still need to do this file stuff in this old way? Serializing (
QDataStream
) might at least be preferable? -
Dumping a QString to a file like that won't be useful. It doesn't have the actual "Section" text within the struct, just a pointer. You need to use structs with "plain old data" types and no complicated classes or pointers if you want to be able to usefully persist them like that. If you want text in such a struct, you have to use a simple fixed length character array. If you want variable length text in a binary file, you need a more complicated format where you store a length for the text data used read values one at a time to figure out how long the reads should be..
-
QString
stores all its data on the heap so your solution can't work.
The correct way:QDataStream &operator<<(QDataStream& out, const Parameters& par){ return out << par.id << par.name << par.temperature_expected; } QDataStream &operator>>(QDataStream& in, Parameters& par){ return out >> par.id >> par.name >> par.temperature_expected; }
QFile file(filename); if(!file.open(QFile::WriteOnly)){ qDebug()<<"Cant open file"; return; } QDatastream writeStream(&file); writeStream << parameters;
QFile file(path); if (!file.open(QIODevice::ReadOnly)){ qDebug()<<"Cant open load file"; return false; } Parameters parameters; QDatastream readStream(&file); readStream >> parameters;