Ошибка сегментации при попытке вставить объекты в массив nullpointers - PullRequest
0 голосов
/ 07 января 2020

Это часть класса, которую мне нужно реализовать.

template <class Element, class Compare = std::equal_to<Element>>
class UniqueArray {
    Element** data;
    unsigned int size;
    unsigned int max_size;
public:
    explicit UniqueArray(unsigned int size);
    UniqueArray(const UniqueArray& other);
    ~UniqueArray();
    unsigned int insert(const Element& element);

Я не могу использовать STL (исключение составляет std::equal_to).

Я реализовал конструкторы как следует:

template <class Element, class Compare>
UniqueArray<Element, Compare>::UniqueArray(unsigned int size):
    data(new Element* [size]), size(0), max_size(size){
}


template <class Element, class Compare>
UniqueArray<Element, Compare>::UniqueArray(const UniqueArray& other):
    data(new Element *[other.size]), size(other.size), max_size(other.max_size){
    for(int i = 0; i < size; i++){
        *data[i] = *other.data[i];
    }
}

data на самом деле массив указателей. каждый указатель указывает на элемент.

Это моя реализация функции insert, которая вызывает SEGFAULT

template <class Element, class Compare>
unsigned int UniqueArray<Element, Compare>::insert(const Element& element){
    if (size >= max_size){
        throw UniqueArrayIsFullException();
    }
    for(int i = 0; i < size; i++){
        if((Compare(), *data[i]) == element){
            return i;
        }
    }

    *data[size++] = element;
    return size;
}

Тест, который я запускаю, таков:

static void testInt() {
    typedef UniqueArray<int, std::equal_to<int>> intUA;
    // Test ctor
    unsigned int size = 4;
    intUA ua(size);
    assert(ua.getSize() == size);
    assert(ua.getCount() == 0);
    // Test insert
    ua.insert(4);
    unsigned int index = ua.insert(1);
    ua.insert(5);
    assert(ua.insert(1) == index);
    ua.insert(2);
    assert(ua.getCount() == 4);
    ua.insert(2);
    // Test UniqueArrayIsFullException
    try {
        ua.insert(3);
    }
    catch (intUA::UniqueArrayIsFullException& e) {
        return;
    }
    assert(0);
}

Тест не пройден при первом вызове insert и указывает, что проблема в строке *data[size++] = element;

Ответы [ 2 ]

1 голос
/ 07 января 2020

Когда вы впервые создаете UniqueArray<Element, Compare>, вы не инициализируете ни один из указателей в массиве.

Если вам повезло, они все являются нулевыми указателями.

Таким образом, при первой попытке вставить элемент через

*data[size++] = element;

запись массива data[size] является нулевым или неинициализированным указателем. Что вы ожидали случиться, когда оценили *data[size]?

1 голос
/ 07 января 2020

Чтобы сделать копию элемента и сохранить ее в data[size++], измените

    *data[size++] = element;

на

    data[size++] = new Element(element);

Дополнительная подсказка: следующее, вероятно, не будет работать так, как это должно работать:

    if((Compare(), *data[i]) == element)

Но у вас есть хороший тест для этого, поэтому он должен его поймать.

...