Этот вопрос закрыт для ответов, так как повторяет вопрос Как исправить ошибку с построчным чтением из бинарного файла C++?

Как исправить ошибку «Нарушение прав доступа при записи по адресу»?

#pragma warning(disable:4996)
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
struct Data {
	int year;
	int mounth;
	int day;
};
struct AutoBase {
	string Name;
	Data Release;
	Data SaleRelease;
};

void input();
void output(string);
AutoBase Divide(AutoBase, string, bool);

int main()
{
	input();
	cout << "\nList of cars";
	output("AutoBase.txt");
}

void input() {
	ofstream In("AutoBase.txt", ios::binary);
	char k = '+';
	AutoBase a;
	string Read;
	while (k == '+') {
		cout << "Enter name of car: "; getline(cin, a.Name);
		cout << "Enter Release Date with a point '10.10.2010': "; getline(cin, Read);
		a = Divide(a, Read, 0);
		cout << "Enter Sale Release Date with a point '10.10.2010': "; getline(cin, Read);
		a = Divide(a, Read, 1);
		cout << "\nEnter '+' in case you want to contnue: "; cin >> k;
		In.write((char*)&a, sizeof(AutoBase));
		cin.ignore();
	}
	In.close();
}

AutoBase Divide(AutoBase a, string Read, bool b) {
	int pos1 = Read.find('.');
	int pos2 = Read.rfind('.');
	if (!b) {
		a.Release.day = stoi(Read.substr(0, pos1));
		a.Release.mounth = stoi(Read.substr(pos1 + 1, pos2));
		a.Release.year = stoi(Read.substr(pos2 + 1));
	}
	else {
		a.SaleRelease.day = stoi(Read.substr(0, pos1));
		a.SaleRelease.mounth = stoi(Read.substr(pos1 + 1, pos2));
		a.SaleRelease.year = stoi(Read.substr(pos2 + 1));
	}
	return a;
}

void output(string name) {
	ifstream Out(name, ios::binary);
	AutoBase a;
	while (Out.read((char*)&a, sizeof(AutoBase))) {
		cout << endl << "Name: " << a.Name << "   Release date:   " << a.Release.day << "." << a.Release.mounth << "." << a.Release.year << "   Slae Release Date:   " << a.SaleRelease.day << "." << a.SaleRelease.mounth << "." << a.SaleRelease.year;
	}
	Out.close();
}


После вывода содержимого файла в консольку выдает ошибку.6228d04475c73324648440.png
  • Вопрос задан
  • 2536 просмотров
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Эта ошибка означает, что вы пишите в какую-то память, которая вам не принадлежит.

Или у вас там неинициализированный указатель, или выход за границы массива, или что-то подобное. Надо присмотреться ко всем указателям в программе.

Можно во время отладки нажать на "продолжить" и тогда дебаггер остановится именно на той инструкции, которая вызвала ошибку. Дальше уже можно смотреть, в какую переменную вы там пишите и откуда она взялась.

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

Поэтому, когда вы его (в составе AutoBase) пишите в файл а потом читаете, вы получаете указатель на адрес, который был жив вместе со старым экземпляром класса. Однако, после удаления этого старого экземпляра, этот адрес уже вам не принадлежит.

Вы можете так писать в файл только структуры из простых типов, и то не всегда (там всякое выравнивание может сыграть с вами злую шутку). Надо писать собственные методы сериализации и десериализации. Строку можно сохранять, например, как длину и потом столько байт, сколько нужно. Тогда при считывании вы сначала чистаете сколько-то байт размера, а потом нужное количество байт в саму строку.
Ответ написан
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы