Выбивает программу с ошибкой -1073741819

189
18 мая 2022, 18:10

В общем есть два класса, один для хранения, другой для добавления строк в базу данных. Полный код программы:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <iomanip>
#include <string>
using namespace std;
class stars {
    char* name;
    double massa;
    double part;
    long long count;
    friend ostream& operator<<(ostream& stream, stars& o1);
    friend istream& operator>>(istream& stream, stars& o1);
    friend void shapka(void);
    friend void linebuild(void);
public:
    stars() { name = 0; count = 0; part = 0; massa = 0; }
    stars( const char* a, double& b, double& c, long long& d);
    void set(char* a, double &, double &, long long &);
    void get(char* a, double& b, double& c, long long& d);
    void show(void);
    char  ret_name() { return *name; }
};
void shapka(void)
{
    cout << "_______________________________________________________________\n";
    cout << "|         Буддистские монастыри Японии периода Нара           |\n";
    cout << "|-------------------------------------------------------------|\n";
    cout << "|  Название  | Школа | Количество монахов | Площадь земли(га) |\n";
    cout << "|-------------------------------------------------------------|\n";
}
void linebuild(void) {
    cout << "\n|-------------------------------------------------------------|\n";
}
class DB {
    char title[30];
    stars* rows[12];
    int col;
    int sorted;
public:
    
    DB(const char* q) { strcpy(title, q); *rows = 0; col = 0; sorted = 0; }
    ~DB() { if (col) for (int i = 0; i < col; i++) delete rows[i]; }
    void add_rec(char* a, double& b, double& c, long long& d);
    void del_rec();
    void sort_DB();
    friend ostream& operator<<(ostream& stream, DB& temp);
};
void DB::add_rec(char* a, double& b, double& c, long long& d) {
    if (col >= 12) return;
    else col++;
    rows[col - 1] = new stars(a, b, c, d);
    sorted = 0;
}
void DB::del_rec() {
    if (col <= 0) return;
    delete  rows[col - 1];
    col--;
}
void DB::sort_DB() {
    char s1;
    char s2;
    if (col < 2) return;
    stars* temp;
    for (int i = 0; i < col; i++)
        for (int j = i + 1; j < col; j++) {
            s1 = rows[i]->ret_name();
            s2 = rows[j]->ret_name();
            if (s1 > s2) {
                temp = rows[i];
                rows[i] = rows[j];
                rows[j] = temp;
            }
        }
    sorted = 1;
}
ostream& operator<<(ostream& stream, DB& o1) {
    stream << o1.title << endl;
    if (o1.sorted == 0) stream << "Таблица не отсортирована.\n";
    else stream << "Таблица отсортирована.\n";
    shapka();
    if (!o1.col) stream << "Таблица пуста.";
    else {
        for (int i = 0; i< o1.col; i++) {
            stream << *o1.rows[i];
        }
    }
    return stream;
}
ostream& operator<<(ostream& stream, stars& o1) {
    stream << "|" << setw(10) << o1.name << "  |  ";
    stream << setw(5) << o1.massa << "|";
    stream << setw(18) << o1.part << "  |";
    stream << setw(17) << o1.count << "  |"<< endl;
    linebuild();
    return stream;
}
istream& operator>>(istream& stream, stars& o1) {
    cout << "Спектральный класс, Приблизительная масса (отн.Солнца),    Часть в процентах, Численность: \n";
    stream >> o1.name;
    stream >> o1.massa;
    stream >> o1.part;
    stream >> o1.count;
    return stream;
}
stars::stars( const char* a, double& b, double& c, long long& d) {
    name = new char[strlen(a) + 1];
    strcpy(name, a);
    massa = b;
    part = c;
    count = d;
}
void stars::set(char* a, double &b, double &c, long long& d) {
    for (int i = 0; i < 10; i++) {
        name[i] = a[i];
    }
    massa = b;
    part = c;
    count = d;
}
void stars::show(void) {
    cout << name << " ";
    cout << massa << " ";
    cout << part << " ";
    cout << count << " ";
}
void stars::get(char* a, double& b, double& c, long long& d)
{
    strcpy(a, name);
    b = massa;
    c = part;
    d = count;
}

int main(void) {
    char* n=nullptr;
    double t;
    double s;
    long long h;
    short i;
    setlocale(LC_ALL, "rus");
    system("cls");
    DB* tmp = new DB("\nБАЗА ДАННЫХ =1\n");
    for (int a = 0; !a;) {
        system("cls");
        cout << "1. Добавить запись\n";
        cout << "2. Удалить запись\n";
        cout << "3. Сортировать базу\n";
        cout << "4. Вывести базу\n";
        cout << "5. Выход\n";
        cout << "> ";
        int p;
        cin >> p;
        switch (p) {
        case 1: {
            cout << "Наименование, Тип, Посевная площадь, Урожайность \n";
            cin>>n;  
             cin>>t;  
             cin>>s;   
             cin>>h;   
             tmp->add_rec(n,t,s,h); 
            //tmp->add_rec("O", 32, 0.0002, 55000);
            //tmp->add_rec("F", 1.25, 2.9, 12000000000);
            //tmp->add_rec("M", 0.2, 73.2, 293000000000);
            break;
        }
        case 2: {
            tmp->del_rec();
            break;
        }
        case 3: {
            tmp->sort_DB();
            break;
        }
        case 4: {
            cout << *tmp;
            cout << "\nНажмите клавишу для продолжения...";
            _getch();
            break;
        }
        case 5: {
            a = 1;
            break;
        }
        default: {
            cout << "Неверный вызов";
            _getch();
            break;
        }
        }
    }
    return 0;
}

Если запустить программу с автозаполнением, то все будет в порядке, но когда идет заполнение с клавиатуры, то после нажатия первого пункта меню и вписывания туда любого значения программа начинает выдавать ошибку и выбивает. Подскажите, пожалуйста, в чем проблема, возможно я не перегрузил >>, буду очень благодарен за ответ. Вот скрин консоли, после чего сразу выбивает:

Answer 1

Давайте разберёмся.

У Вас первой же строкой идёт: char* n=nullptr;. То есть Вы объявляете указатель на данные типа char и делаете этот указатель равным некоему недействительному числу (условно – нулю).

Далее Вы используете оператор cin, который, по сути, "говорит" компьютеру: "считай данные и положи их туда, куда тебе указывает указатель". А теперь вспомним, что указатель у нас указывает на nullptr, то есть, в никуда. Компьютер, конечно, попробует записать считанные данные в нулевой адрес в памяти, но на то он и nullptr, что запись по нему запрещена в любом случае.

Кто виноват, разобрались. Теперь посмотрим, что делать. Очевидно, необходимо сделать так, чтобы n указывал на некую действительную и доступную для записи область памяти. Делается это, как вариант, с помощью оператора new. Например, так:

char* n = new char[максимальный размер вводимой строки + 1]; 

Замените Вашу первую строку в main этим, укажите в квадратных скобках нужное число и, думаю, проблема исчезнет.

P.S. Почему в квадратных скобках стоит +1 могу пояснить, если нужно. Сразу в ответ включать не стал, т.к. не совсем относится к сути вопроса.

READ ALSO
cUrl запрос с конкретного интерфейса

cUrl запрос с конкретного интерфейса

Имеется ОС Linux, libcurl 768

199
Профилирование gprof

Профилирование gprof

Помогите разобратьсяКуча мануалов по gprof - но они не понятные

228
Смена знака с + на - в цикле С++

Смена знака с + на - в цикле С++

Я новичок в программировании,нужно написать цикл в котором сумма будет считаться как 1-1/2+1/3-1/4+1/5-1/6 и тд,не совсем понимаю как менять знак с + на - в цикле

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

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

Найти произведение элементов одномерного массива, состоящего из N элементовРазмер массива и его элементы вводятся с клавиатуры

205