Как в C++ создать массив структур неизвестной длины внутри функции?

В теле main() я создаю переменную-указатель на структуру, которая передается в функцию, где вводится количество элементов массива и создается массив. При попытке ввода поля в первый элемент массива программа вылетает. Где у меня ошибка, и возможно ли вообще так создать этот массив?
struct publisher{
    int year;
    char name[maxL], city[maxL];
};

struct book{
    publisher pubhouse;
    char name[maxL], auth[maxL];
    int price, page_n;
};

void input (book *books, int *n){
    int i;
    printf("Введите количество книг: ");
    scanf("%d", n);
    books = new book[*n];
    printf ("\nВведите данные о книгах:");
    for (i = 0; i < *n; i++){
        printf("\nКнига #%d\n", i + 1);
        printf("Введите название книги: ");
        scanf("%s", *books[i].name);
        printf("\nВведите имя автора: ");
        gets(books[i].auth);
        printf("\nВведите цену книги: ");
        scanf("%d", books[i].price);
        printf("\nВведите количество страниц: ");
        scanf("%d", books[i].page_n);
        printf("Введите имя издательства: ");
        gets(books[i].pubhouse.name);
        printf("Введите имя города: ");
        gets(books[i].pubhouse.city);
        printf("\nВведите год издания: ");
        scanf("%d", books[i].pubhouse.year);
    }
}

int main()
{
    setlocale(LC_ALL, "RUS");
    int i, j, n, k;
    book *books;
    input(books, &n);
    delete [] books;
    return 0;
}
  • Вопрос задан
  • 6698 просмотров
Пригласить эксперта
Ответы на вопрос 4
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Ошибка:
scanf("%s", *books[i].name); Вы вместо указателя на имя передаёте значение первого символа, правильно:
scanf("%s", books[i].name);
Ошибка:
scanf("%d", books[i].price);
scanf("%d", books[i].page_n);
scanf("%d", books[i].pubhouse.year);
Вы вместо адреса переменной передаёте её значение, правильно:
scanf("%d", &(books[i].price));
scanf("%d", &(books[i].page_n));
scanf("%d", &(books[i].pubhouse.year));
Ответ написан
Комментировать
@encyclopedist
Во-первых, ваш код - это С а не С++. В С++ стоило бы использовать std::vector и что-то более безопасное вместо scanf и gets.

По вашему коду: обратите внимание на строчки со scanf. Вторым аргументом должен быть указатель на переменную, однако в строке
scanf("%d", books[i].price);вы передаёте туда саму цену, а не указатель на неё. Ещё раз перепроверьте все эти строки.

И компилируйте с макимальным уровнем предупреждений (например в GCC это -Wall -Wextra), современные компиляторы способны определять несоответствие типов в printf/scanf.
Ответ написан
Кроме упомянутых выше ошибок с использованием scanf (и сомнительности использования gets), есть еще одна ошибка связанная с передачей указателя в функцию input - он передается по значению, и изменяется версия внутри функции, но не значение переменной books из main, соответственно, delete [] books - делает совсем не то, что вы ожидаете.
Ответ написан
Комментировать
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Почему бы вам не использовать списки?

А ответ довольно простой - память под массив вы выделили, а структуру не инициализировали.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы