Запись обьекта с STL string, list, vector в бинарный файл

пытаюсь записать в бинарный файл обьект 'студент', кажется что-то не то с записью контейнеров, вот код, не знаю что еще добавить, исправляю уже час, всё никак.

class StudentA {
    string surname;
    string name;
    int age;
    string vuz;
    vector<int> marks;
    list<string> subjects;
//...
}


void StudentA::write_to_file(ofstream& os)
{
    size_t sz = surname.length() + 1;
    os.write((char*)&sz, sizeof(sz));
    os.write((char*)surname.c_str(), sz);
    sz = name.length() + 1;
    os.write((char*)&sz, sizeof(sz));
    os.write((char*)name.c_str(), sz);
    os.write((char*)&age, sizeof(age));
    sz = vuz.length() + 1;
    os.write((char*)&sz, sizeof(sz));
    os.write((char*)vuz.c_str(), sz);
    sz = sizeof(marks);
    os.write(reinterpret_cast<const char*>(&sz), sizeof(sz));
    os.write(reinterpret_cast<const char*>(&marks[0]), sz * sizeof(marks[0]));
    //...............................   //CONTINUE

    sz = sizeof(subjects);
    os.write((char*)&sz, sizeof(sz));
    for (auto val : subjects)
    {
        os.write((char*)val.c_str(), sizeof(val));
    }
    //CONTINUE
}
void StudentA::read_from_file(ifstream& in)
{
    size_t sz;                        
    in.read((char*)&sz, sizeof(sz));
    char* buf = new char[sz];
    in.read(buf, sz);
    surname = buf;
    delete[]buf;
    in.read((char*)&sz, sizeof(sz));
    buf = new char[sz];
    in.read(buf, sz);
    name = buf;
    delete[]buf;
    in.read((char*)&age, sizeof(age));
    in.read((char*)&sz, sizeof(sz));
    buf = new char[sz];
    in.read(buf, sz);
    vuz = buf;
    delete[]buf;
    const size_t count = sizeof(*this) / sizeof(int);
    vector<int> vec(count);
    in.read(reinterpret_cast<char*>(&vec[0]), count * sizeof(int));
    //...............................   //CONTINUE

    in.read((char*)&sz, sizeof(sz));
    for (; sz > 0; sz -= sizeof(string))
    {
        buf = new char[sizeof(string)];
        in.read(buf, sz);
        subjects.push_back(buf);
        delete[]buf;
    }
    //CONTINUE
}

Ответы (1 шт):

Автор решения: gbg

Правило примерно такое - не сбрасывать в файл объекты, которые прямо или косвенно содержат ссылки или указатели.

Код ниже:

in.read((char*)&sz, sizeof(sz));
for (; sz > 0; sz -= sizeof(string))
{
    buf = new char[sizeof(string)];
    in.read(buf, sz);
    subjects.push_back(buf);
    delete[]buf;
}

Не работает именно по этой причине. Так что делайте как в коде выше - записывайте длину строки, а потом ее содержимое.

Еще одна проблема - то как вы читаете строки из файла. Нерационально выделять временный буфер - можно сразу задавать вашим строкам нужный размер:

size_t sz;                        
in.read((char*)&sz, sizeof(sz));
surname.resize(sz);
in.read(surname.data(), sz);
→ Ссылка