Eliran Turgeman
Eliran Turgeman

Reputation: 1656

Segmentation fault while trying to insert objects to nullpointers array

This is a part of a class I need to implement.

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);

I can't use STL (only exception is std::equal_to).

I implemented the constructors as follows :

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 is actually an array of pointers. each pointer points to an Element.

This is my implementation of insert function which causes 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;
}

The test im running is this :

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);
}

Test fails at the first call to insert and points that the problem is in line *data[size++] = element;

Upvotes: 0

Views: 163

Answers (2)

David K
David K

Reputation: 3132

When you first construct a UniqueArray<Element, Compare>, you do not initialize any of the pointer in the array.

If you are lucky, they are all null pointers.

So the first time you try to insert an element via

*data[size++] = element;

the array entry data[size] is a null or uninitialized pointer. What did you expect to happen when you evaluate *data[size]?

Upvotes: 1

rustyx
rustyx

Reputation: 85452

To make a copy of the element and store it at data[size++], change

    *data[size++] = element;

To

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

Bonus hint: the following probably won't work the way it's meant to work:

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

But you have a nice test for it, so it should catch it.

Upvotes: 1

Related Questions