C ++ - ошибка при вставке элементов в массив в порядке возрастания - PullRequest
1 голос
/ 04 февраля 2020

Как часть класса BookGroup, который управляет массивом объектов Book, меня попросили создать функцию-член void add(Book* b), которая добавляет указанный Book b к массиву книг в правильном месте. (от самого старого до самого последнего года публикации). Мне необходимо сместить элементы массива в направлении задней части массива, чтобы освободить место для нового элемента на его правильном месте. Мне не разрешено просто добавлять в конец массива, а затем сортировать или использовать любую функцию сортировки / алгоритм сортировки в массиве.

Я попытался протестировать свою функцию добавления и получил ошибку сегмента. Мой подход состоял в том, чтобы добавить любую новую книгу в конец массива, и если указанный вами c год издания книги был старше (число меньше), чем последняя книга в массиве, я бы заставил две книги поменяться местами. Если нет, книга останется на том же месте в самом конце массива. Затем я продолжаю этот процесс.

Я не знаю, что является причиной ошибки сегмента. В качестве примечания мне было интересно, должен ли я использовать функцию удаления в любой точке add()? Я сделал проверку valgrind на моем компиляторе, и он говорит, что где-то в моей программе потеряна куча байтов. Я предполагаю, что хороший кусок байтов, вероятно, исходит от функции добавления, но я не уверен и просто хотел перепроверить.

bookCollection должен быть статически распределенным массивом Book указатели объектов. Есть два класса - Book. cc и BookGroup. cc.

Я решил показать весь свой код, чтобы люди могли его скомпилировать, но, пожалуйста, публикуйте только то, что необходимо, и воздерживайтесь от публикации всего этого в ответах ниже.

BookGroup. cc:

#include <iostream>
#include <iomanip>
using namespace std;
#include "BookGroup.h"

BookGroup::BookGroup(int n){ 
  numOfBooks = n; 
}

void BookGroup::add(Book* b){ 

    if(numOfBooks != MAX_BOOKS){
        if(numOfBooks == 0){
            bookCollection[0] = b; //add first element
            ++numOfBooks; //increase numOfBooks by 1 and go to next statement
        }else{
            for(int i = numOfBooks-1; i >= 0; --i){ //start at end of array and work towards front where lowest years are
                if(b->getPubYear() < bookCollection[i]->getPubYear()){
                    bookCollection[i + 1] = bookCollection[i]; //swap positions if b is lower than last element
                    bookCollection[i] = b;
                }else{
                    b = bookCollection[i + 1]; //otherwise stay in the same spot (keep b at the end)
                    //break;
                }
            }
            ++numOfBooks;
        }

    }
    cout<<"Book could not be added to collection. No more space "<<endl; 
}

BookGroup.h:

#ifndef BOOKGROUP_H
#define BOOKGROUP_H
#define MAX_BOOKS 15
#include <string>
using namespace std;

class BookGroup
{
    public:
        BookGroup(int);
        BookGroup(BookGroup&);  
        ~BookGroup();
        void print();
        void add(Book*);
        Book* bookCollection[MAX_BOOKS];

    private: 
        int numOfBooks;

};
#endif

Book. cc: https://pastebin.com/9swrwYgx

Book.h: https://pastebin.com/mqDn2C30

makefile: https://pastebin.com/xHKDsVL1

main: https://pastebin.com/TBzyduMC

Когда я пытаюсь запустить его:

Объявление двух групп книг ...

Инициализация двух групп книг ...

- по умолчанию Книжный cтор: Питер Пэн год: 1982

Ошибка сегментации

1 Ответ

0 голосов
/ 04 февраля 2020

Этот

BookGroup::BookGroup(int n){ 
  numOfBooks = n; 
}

вместе с этим

BookGroup suzy(2);

создает группы книг, которые не содержат указателей на действительные книги, но ДОЛЖНЫ притворяться, что содержат 2.

Тогда здесь

for(int i = numOfBooks-1; i >= 0; --i)
{ //start at end of array and work towards front where lowest years are
    if(b->getPubYear() < bookCollection[i]->getPubYear()){

вы начинаете обращаться к индексу 1 (из-за numBooks == 2), который не является допустимым указателем.

Вы должны

  • правильно инициализируйте ваш массив, например, с помощью NULL, чтобы убедиться, что проверки работают корректно позже
  • дважды проверьте, что вы используете только допустимый указатель, везде, при необходимости дважды
  • не инициализируйте пустую группу с не -Нулевое количество выдаваемых книг
...