2015-02-06 3 views
1

Я пытаюсь динамически выделять массив записей. Когда я запускаю свою программу с ./a.out, она работает нормально, но когда я пытаюсь запустить программу, введя данные из TXT-файла (./myProg <), он многократно записывает первую строку текста во весь массив и сбой и не распечатывает выбранную книгу в конце. Я предполагаю, что я не создаю массив правильно, но я не могу понять, что моя проблема.Динамически выделять массив структур с помощью C++

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; 
} 
+0

Используйте 'станд :: VECTOR'. –

ответ

5

Ну, во-первых, вы будете выделять два массива:

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

Это утечка памяти.

Во-вторых:

(bookArr[i]).title = new char 

Это выделяет один единственный символ, который вы пытаетесь скопировать всю строку в. Это, вероятно, следует:

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

В-третьих:

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

Это ограничивает проверку неверен. Верхняя граница должна быть n < arrN, а затем просто указана n. По индексированию n - 1 вы можете распечатать -1-й индекс.

И последнее, но не менее, предпочитают:

struct Book { 
    std::string title; 
    int date; 
} 

std::vector<Book> bookArr; 
0

задачи1:

Устранить проблему индексации массива в функции отображения:

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

к

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

когда n = 0, bookArr[-1] выдает ошибку в вашем коде.

Задача 2:

Выделяют символьный массив вместо одного символа в названии в строке, изменения:

strcpy((bookArr[i]).title = new char, arrFirst); 

в

strcpy((bookArr[i]).title = new char[20], arrFirst); 
-1

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

Это то, что вы должны делать ...

// Allocate an array of books 
Book *bookArr; 
bookArr = new Book[arrN]; 

// Preallocate the records 
for (int iBook = 0; iBool < arrN; iBook++) 
{ 
    bookArr[ iBook ] = createRecord(); 
} 

... 


Book *createRecord() 
{ 
    // Allocate one new book 
    struct Book *pbook = new book; 
    return pbook; 
} 
Смежные вопросы