Ошибка чтения / записи массива структуры в двоичном файле в переполнении стека

Я хочу записать структуру моего массива в двоичный файл.

Моя структура

typedef struct student{
char name[15];
vector<int> grade;
}arr_stu;

Я могу писать и читать мои данные, если я пишу и читаю в одной программе; но если я создаю другую программу только для чтения данных и помещаю двоичный файл, она не работает, потому что векторное значение равно нулю.

size = 0;
unable to read from memory

Программа для записи структуры массива в файл

int main()
{
arr_stu stu[100];

for (size_t i = 0; i < 100; i++)
{
strcpy(stu[i].name, randomName());
for (size_t j = 0; j < 10; j++)
{
stu[i].grade.push_back(randomGrade());
}
}

ofstream outbal("class", ios::out | ios::binary);
if (!outbal) {
cout << "Cannot open file.\n";
return 1;
}

outbal.write((char *)&stu, sizeof(stu));
outbal.close();
}

Программа для чтения структуры массива в файл

int main(){

feature_struc stu[100];

ifstream inbal("class", ios::in | ios::binary);
if (!inbal) {
cout << "Cannot open file.\n";
return 1;
}

inbal.read((char *)&stu, sizeof(stu));

for (size_t idx = 0; idx < 100; idx++)
{
cout << "Name :  " << stu[idx].name << endl;
for (size_t index = 0; index < 10; index++)
{
cout << endl << "test: " << stu[idx].grade[index] << endl;
}
}
inbal.close();
return 0;
}

Для меня кажется, что использование вектора создает проблему,
Я думаю, что если мы скомбинируем два в одной программе, это будет работать хорошо, потому что вектор сохраняется в памяти, поэтому он все еще доступен.

Какие-либо предложения?

1

Решение

Вы не можете сериализовать такой вектор. write а также read функции обращаются к памяти по указанному адресу напрямую. поскольку vector это сложный тип класса, только части его содержимого хранятся последовательно по его базовому адресу. Другие части (выделенная куча памяти и т. Д.) Расположены в других местах. Самое простое решение — записать длину вектора в файл, за которым следует каждое из значений. Вы должны перебрать элементы вектора, чтобы выполнить это.

4

Другие решения

outbal.write((char *)&stu, sizeof(stu));

sizeof является константой времени компиляции. Другими словами, это никогда не меняется. Если вектор содержал 1, 10, 1000 или 1 000 000 элементов, вы записываете в файл одинаковое количество байтов. Так что этот способ записи в файл совершенно неверен.

Структура, которую вы пишете non-POD из-за vector будучи не POD типом. Это означает, что вы не можете просто рассматривать его как набор байтов, с которых вы можете скопировать или в которые. Если вам нужны дополнительные доказательства, откройте файл, который вы создали в любом редакторе. Можете ли вы увидеть данные из вектора в этом файле? То, что вы увидите, более чем вероятно, бред.

Чтобы записать данные в файл, вы должны правильно сериализовать данные, то есть вы должны записать данные в файл, а не в struct сам. Вы записываете данные таким образом, что когда вы читаете их обратно, вы можете воссоздать структуру. В конечном итоге это означает, что вы должны

  1. Запишите имя в файл и, возможно, количество байтов, из которых состоит имя.
  2. Напишите количество элементов в векторе
  3. Запишите каждый элемент вектора в файл.

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

1

Какой формат двоичного файла? По сути, вы должны
определить формат, а затем преобразовать каждый элемент в и из
этот формат. Вы никогда не можете просто сбросить биты внутреннего
представление на диск и ожидать, чтобы иметь возможность прочитать его обратно.
(Тот факт, что вам нужно reinterpret_cast звонить
ostream::write на вашем объекте должен вам кое-что рассказать.)

0
По вопросам рекламы [email protected]