Search code examples
c++arraysdynamic-memory-allocationrecords

Dynamically allocate an array of structs with C++


I am trying to dynamically allocate an array of records. When I run my program with ./a.out it appears to work fine but when I try and run the program inputing the data from a .txt file (./myProg < ) it repeatedly records the first line of text in the whole array and crashes and does not print out the chosen book in the end. My guess is I am not creating the array properly but I cannot seem to figure out what my problem is.

struct Book {
    char *title; //entered with no spaces
    int date; // in the form ddmmyy
};

Book *createRecord(int);
void input(Book *, int);
void display(Book *, int, int);
void destroyRecord(Book *);

int main() {
    int arrN = 0;
    int n = 0;

    cout << "Enter size of array: ";
    cin >> arrN;

    Book *bookArr;  
    bookArr = new Book[arrN];

    bookArr = createRecord(arrN);

    input(bookArr, arrN);

    cin.ignore();
    cout << "Book: ";
    cin >> n;

    display(bookArr, arrN, n);  
    destroyRecord(bookArr);

    return EXIT_SUCCESS; 
}


Book *createRecord(int arrN){
    struct Book *bookArr;
    bookArr = new Book[arrN];
    return bookArr;
}

void input(Book *bookArr, int arrN) {
    for(int i = 0; i < arrN; i++){
        char arrFirst[20];
        cin.ignore();
        cout << "Name: ";
        cin.getline(arrFirst, 20);
        strcpy((bookArr[i]).title = new char, arrFirst);
        cout << "Score: ";
        cin >> (bookArr[i]).date;
    }
}


void display(Book *bookArr, int arrN, int n) {
    if (0 <= n && n <= arrN){
        cout << (bookArr[n-1]).title << " " << (bookArr[n-1]).date << endl;
    }
}

void destroyRecord(Book *bookArr) {
   delete [] (bookArr)->title;
   delete bookArr;
}

Solution

  • Well, first up, you're allocating two arrays:

    bookArr = new Book[arrN]; // <-- leaked
    bookArr = createRecord(arrN);
    

    That's a memory leak.

    Secondly:

    (bookArr[i]).title = new char
    

    That is allocating one single char that you're trying to copy a whole string into. That should probably be:

    // two lines please!
    bookArr[i].title = new char[20];
    strcpy(bookArr[i].title, arrFirst);
    

    Thirdly:

    if (0 <= n && n <= arrN){
    

    That bounds check is incorrect. The upper bound should be n < arrN, and then just index n. By indexing n - 1, you might print the -1st index.

    And last, but not least, prefer:

    struct Book {
        std::string title;
        int date;
    }
    
    std::vector<Book> bookArr;