Проблема с добавлением элементов в динамический массив структур

Когда функция addBOOK запускается второй раз, новая книга туда не добавляется, как будто размер массива и не увеличился

Первый раз работаю с функциями, массивами и структурами одновременно, не пойму, в чем дело

В исходнике функция main и menu лежат в одном файле, остальные в другом, объявляются все в третьем.

Необходимая часть кода

#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <fstream>
#include <string>
#include <vector>

#include "book.h"

struct BOOK {
    std::string author;
    std::string header;
    int year;
    int price;
};
bool menu(BOOK** library, int* size);
BOOK create();
void addBOOK(BOOK** library, int* size);
int main() {
    using namespace std;
    setlocale(LC_ALL, "rus");

    
    int size = 0;
    BOOK* library = new BOOK[size];
    while(menu(&library, &size));

    return 0;
}
void menu(BOOK* library, int* size) {
    printf("%s", "Выберите действие(введите его номер):\n \
Распечатать содержимое картотеки (1)\n \
Ввести новую книгу (2)\n \
Удалить существующую(ие) (3)\n \
Записать текущее содержимое картотеки в файл (4)\n \
Считать из файла содержимое в картотеку (5) \n \
Выход из прогрмаммы (6) \n");
    int action = _getch();


    switch (action) { // Win - 1251

    case 50: addBOOK(library, size); return true; // 2

    default: printf("%s", "Такого действия не существует, выберите заново..."); menu(library, size); return true;

    }
}

void addBOOK(BOOK** library, int * size) { // добавление новой книги в картотеку
    // Записали новую книгу
    BOOK book = create(); 
    // Скопировали картотеку и добавили новую книгу
    (*size)++;
    BOOK* temp = new BOOK[*size];
    for (int i = 0; i < *size - 1; ++i) {
        temp[i] = (*library)[i];
    }
    temp[*size - 1] = book;
    // Перезаписали исходную картотеку, добавив книгу
    delete[] *library;
    *library = new BOOK[*size];
    for (int i = 0; i < *size; ++i) {
        (*library)[i] = temp[i];
    }
    delete[] temp;
}

BOOK create() { // Создание записи новой книги
    std::string author, header;
    int price = 0;
    int year = 0;
    
    printf("%s", "Введите Автора, заголовок, год издания и стоимость книги, которую хотите добавить\n");
    //scanf_s("%s%s%i%i", author, header, year, price); // error
    cin >> author >> header >> year >> price;

    BOOK book;
    book.author = author;
    book.header = header;
    book.price = price;
    book.year = year;

    return book;
}

Ответы (1 шт):

Автор решения: NunOfIt

в функции addBOOK переменная library является указателем, не ссылкой. Давайте представим, что у вас есть некая переменная int a = 5; и вы её передаёте в функцию void func(int x) { x = 10; }, изменится ли переменная a после func(a);? Правильный ответ нет, не изменится, т.к. в функцию func передаётся копия переменной a, а не ссылка на неё. Так же и в данном случае, вы передаёте в функцию копию указателя на динамический массив, если вы там в функции например напишите library = nullptr;, то сама переменная которую вы передавали в функцию не изменится, ибо вы передавали не ссылку на указатель или указатель на указатель, а копию указателя...

Можно ваш код исправить как-то так, но я бы порекомендовал не изобретать колесо и использовать std::vector

#include <string>
#include <iostream>

struct BOOK {
    int year;
    int price;
    std::string author;
    std::string header;
};

class Library {
    size_t size_;
    BOOK* library_;

public:
    Library(): size_(0), library_(nullptr) {}

    void push_back(const BOOK& book) {
        BOOK* temp;

        temp = new BOOK[size_ + 1];
        for(size_t i = 0; i < size_; ++i) { temp[i] = library_[i]; }
        temp[size_] = book;

        delete[] library_;
        library_ = temp;
        ++size_;
    }

    BOOK* library() { return library_; }
    size_t size() const { return size_; }
};

BOOK create();
bool menu(Library&);

int main() {
    setlocale(LC_ALL, "rus");
    
    Library lib;
    while(menu(lib));

    return 0;
}

bool menu(Library& lib) {
    int action;
    std::cout << "Выберите действие(введите его номер):\n"
                 "Распечатать содержимое картотеки (1)\n"
                 "Ввести новую книгу (2)\n"
                 "Удалить существующую(ие) (3)\n"
                 "Записать текущее содержимое картотеки в файл (4)\n"
                 "Считать из файла содержимое в картотеку (5)\n"
                 "Выход из прогрмаммы (6)\n"
                 "---> ";

    std::cin >> action;
    switch (action) {
        case 2:
            lib.push_back(create());
            return true;
        
        case 6:
            return false;

        default:
            std::cout << "Такого действия не существует, выберите заново...";
            return true;
    }
}

BOOK create() {
    BOOK book;
    std::cout << "Введите информацию о книге "
                 "(Автор Заголовок Год издания Стоимость):\n"
                 "---> ";
    
    std::cin >> book.author >> book.header >> book.year >> book.price;
    return book;
}
→ Ссылка