-3
#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;
    }
  • Где именно? Или вы всерьез считаете, что кто-то будет рассматривать ваш некомпилируемый код глазами в попытках найти ошибку среди более чем 200 строк? Кстати, это - if (!in.eof()) { in >> f; } - было бы ошибкой (не связанной с памятью), если бы не было так бессмысленно... Вашу же ошибку ищите где-то при выделении памяти. Подозреваю, что это где-то в той части исходников, которые вы старательно спрятали... – Harry Jun 02 '21 at 04:24

1 Answers1

0

Такая ошибка в 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); // ЭТО ПЛОХОЙ КОД, НИКОГДА ТАК НЕ ПИШИТЕ

После этих модификаций я думаю Вы быстро найдете, что у Вас с файла читается совсем не то, что Вы ожидаете и все будет пофикшено.

KoVadim
  • 112,121
  • 6
  • 94
  • 160