#include "filmlibrary.h"
#include<stdio.h>
#include<conio.h>
#include<iostream>
#include<string.h>
#include<fstream>
using namespace std;
filmlibrary::filmlibrary()
{
movie = NULL;
count = 0;
}
filmlibrary::~filmlibrary()
{
delete[] this->movie;
movie = NULL;
count = 0;
}
void filmlibrary::menu()
{
cout << "1.Добавить фильм." << endl;
cout << "2.Найти фильм по названию." << endl;
cout << "3.Найти фильм по году." << endl;
cout << "4.Найти фильмы по режиссеру." << endl;
cout << "5.Узнать текущее число фильмов." << endl;
cout << "6.Удалить фильм по названию." << endl;
}
void filmlibrary::menuUSE(filmlibrary& f)
{
cout << "выберите функцию" << endl;
cin >> choosing;
for (;;) {
switch (choosing) {
case 1:
{ ifstream in("file.txt");
if (!in.eof()) {
in >> f;
}
in.close();
cin >> f;
ofstream out("file.txt");
out << f;
out.close();
break;
}
case 2:
{
ifstream in("file.txt");
if (!in.eof()) {
in >> f;
}
in.close();
string NAMEFILM;
cin.seekg(2, cin.cur);
getline(cin, NAMEFILM);
cout << endl;
for (int i = 0; i < f.count; i++) {
if (NAMEFILM == f.movie[i].name) {
cout << "Название: " << f.movie[i].name << endl;
cout << "Режиссер: " << f.movie[i].director << endl;
cout << "Сценарист: " << f.movie[i].scenario << endl;
cout << "Композитор: " << f.movie[i].compositor << endl;
cout << "Дата выхода в прокат: " << f.movie[i].hiredate << endl;
cout << "Сборы: " << f.movie[i].cash + "rub" << endl;
cout << "Год выхода: " << f.movie[i].year << endl;
}
}
break;
}
case 3:
{
ifstream in("file.txt");
if (!in.eof()) {
in >> f;
}
in.close();
string YEARFILM;
cin.seekg(2, cin.cur);
getline(cin, YEARFILM);
cout << endl;
for (int i = 0; i < f.count; i++) {
if (YEARFILM == f.movie[i].year) {
cout << "Название: " << f.movie[i].name << endl;
cout << "Режиссер: " << f.movie[i].director << endl;
cout << "Сценарист: " << f.movie[i].scenario << endl;
cout << "Композитор: " << f.movie[i].compositor << endl;
cout << "Дата выхода в прокат: " << f.movie[i].hiredate << endl;
cout << "Сборы: " << f.movie[i].cash + "rub" << endl;
cout << "Год выхода: " << f.movie[i].year << endl;
}
}
break;
}
case 4:
{
ifstream in("file.txt");
if (!in.eof()) {
in >> f;
}
in.close();
string FILMDIRECTOR;
cin.seekg(2, cin.cur);
getline(cin, FILMDIRECTOR);
cout << endl;
for (int i = 0; i < f.count; i++) {
if (FILMDIRECTOR == f.movie[i].director) {
cout << "Название: " << f.movie[i].name << endl;
cout << "Режиссер: " << f.movie[i].director << endl;
cout << "Сценарист: " << f.movie[i].scenario << endl;
cout << "Композитор: " << f.movie[i].compositor << endl;
cout << "Дата выхода в прокат: " << f.movie[i].hiredate << endl;
cout << "Сборы: " << f.movie[i].cash+"rub" << endl;
cout << "Год выхода: " << f.movie[i].year << endl;
}
}
break;
}
case 5:
{
ifstream in;
in.open("file.txt");
if (!in.eof()) {
in >> f;
}
cout << f.count;
break;
}
case 6://удалить фильм по названию
{
ifstream in("file.txt");
if (!in.eof()) {
in >> f;
}
in.close();
string DELETENAME;
cin.seekg(2, cin.cur);
getline(cin, DELETENAME);
cout << endl;
for (int i = 0; i < f.count; i++) {
if (DELETENAME == f.movie[i].director) {
delete[] this->movie;
}
}
break;
}
}
}
}
istream& operator>>(istream& in, filmlibrary& f)
{
f.count = f.count + 1;
in >> f.count;
f.movie = new filmlibrary[f.count];
ifstream in2("file.txt");
in.seekg(2, in.cur);
in2.seekg(2, in2.cur);
for (int i = 0; i < f.count; i++) {
getline(in2, f.movie[i].name);
getline(in2, f.movie[i].director);
getline(in2, f.movie[i].scenario);
getline(in2, f.movie[i].compositor);
getline(in2, f.movie[i].hiredate);
getline(in2, f.movie[i].cash);
getline(in2, f.movie[i].year);
in2.seekg(2, in2.cur);
}
getline(in, f.movie[f.count-1].name);
getline(in, f.movie[f.count - 1].director);
getline(in, f.movie[f.count - 1].scenario);
getline(in, f.movie[f.count - 1].compositor);
getline(in, f.movie[f.count - 1].hiredate);
getline(in, f.movie[f.count - 1].cash);
getline(in, f.movie[f.count - 1].year);
return in;
}
ifstream& operator>>(ifstream& in, filmlibrary& f)
{
in >> f.count;
f.movie = new filmlibrary[f.count];
in.seekg(2, in.cur);
for (int i = 0; i < f.count; i++) {
getline(in, f.movie[f.count - 1].name);
getline(in, f.movie[f.count - 1].director);
getline(in, f.movie[f.count - 1].scenario);
getline(in, f.movie[f.count - 1].compositor);
getline(in, f.movie[f.count - 1].hiredate);
getline(in, f.movie[f.count - 1].cash);
getline(in, f.movie[f.count - 1].year);
in.seekg(2, in.cur);
}
return in;
}
ofstream& operator<<(ofstream& out, const filmlibrary& f)
{
out << f.count;
for (int i = 0; i < f.count; i++) {
out << f.movie[i].name << endl;
out << f.movie[i].director << endl;
out << f.movie[i].scenario << endl;
out << f.movie[i].compositor << endl;
out << f.movie[i].hiredate << endl;
out << f.movie[i].cash << endl;
out << f.movie[i].year << endl;
}
return out;
}
- 7
1 Answers
Такая ошибка в 99% случаев возникает, если в new передать неверный размер. Детали https://en.cppreference.com/w/cpp/memory/new/bad_array_new_length
В коде есть всего два места, где такое может быть
f.count = f.count + 1;
in >> f.count;
f.movie = new filmlibrary[f.count];
это очень очень странное место. Перевыделяем память. Старое содержимое теряется и приводит к утечке. Это уже печально. Скорее всего Вам тут просто нужен обычный vector или не забудьте удалить старые данные.
Но тут есть ещё большой слон, которого я сразу и не приметил. В первой строке увеличивается на 1 (выглядит ок), потом с потока читаем новое значение. ой. а зачем тогда нужно было увеличивать?
И нет никакого контроля, что именно прочиталось. Если там слишком большое число или отрицательное (так говорит документация, хотя сам new принимает size_t), то как раз и будет указанная ошибка.
Вывод. Проверяйте, что именно там прочиталось и делайте соответствующие выводы.
я бы как минимум после ввода делал такую проверку
if (in >> f.count) {
std::cout << "ничего не удалось ввести";
exit(1);
}
if (f.count <= 0 || f.count > 10000) {
std::cout << "oops, count очень большой или маленький, что то пошло не так";
exit(1);
}
я не знаю типа f.count, если он беззнаковый, то первое сравнение бессмысленное. Но даже в этом случае ввод нуля должен вызвать подозрения.
А самое первое условие проверяет, что ввод вообще произошел.
Можно вместо таких условий использовать assert, но главное не пишите так
assert(in >> f.count); // ЭТО ПЛОХОЙ КОД, НИКОГДА ТАК НЕ ПИШИТЕ
После этих модификаций я думаю Вы быстро найдете, что у Вас с файла читается совсем не то, что Вы ожидаете и все будет пофикшено.
- 112,121
- 6
- 94
- 160
if (!in.eof()) { in >> f; }- было бы ошибкой (не связанной с памятью), если бы не было так бессмысленно... Вашу же ошибку ищите где-то при выделении памяти. Подозреваю, что это где-то в той части исходников, которые вы старательно спрятали... – Harry Jun 02 '21 at 04:24