Сегментация сбоев в шаблонах c ++ - PullRequest
0 голосов
/ 10 сентября 2010

Я написал свой первый шаблонный код C ++ для расширяемого массива, и у меня ошибка сегментации!После часа отладки я понял, что мне нужна помощь.Что-то не так с конструктором или деструктором, я думаю, но не уверен.

Код на pastie готов к компиляции.http://pastie.org/1150617

/* Expandable array in C++ */

#include <iostream>
using namespace std;

template <class T>
class EArray{
private:
    T* arr;
    int size;
public:
    EArray(int l);
    ~EArray();

    void setElement(int i, const T& newval);
    void eraseElement(int i);
    void addElement(int i, const T& newval);
    void push(const T& newval);
    void display();
};

template <class T>
EArray<T>::EArray(int l){
    size = l;
}

template <class T>
EArray<T>::~EArray(){
    delete [] arr;
    arr = NULL;
}

template <class T>
void EArray<T>::setElement(int i, const T& newval){
    if(i < size && i >= 0){
        arr[i] = newval;
    }
}

template <class T>
void EArray<T>::eraseElement(int index){
    size -= 1;
    T* newarr = new T[size];
    for (int i = 0; i < size+1; i++){
        if (i < index){
            newarr[i] = arr[i];
        }
        else if(i > index){
            newarr[i-1] = arr[i];
        }
    }
    delete [] arr;
    arr = newarr;
}

template <class T>
void EArray<T>::addElement(int index, const T& newval){
    size += 1;
    T* newarr = new T[size];
    for(int i = 0; i < size; i++){
        if(i<index){
            newarr[i] = arr[i];
        }
        else if (i == index){
            newarr[i] = newval;
        }
        else{
            newarr[i] = arr[i-1];
        }
    }
    delete [] arr;
    arr = newarr;
}

template <class T>

void EArray<T>::push(const T& newval){
    size += 1;
    T * newarr = new T[size];
    for (int i = 0; i < size-1; i++){
        newarr[i] = arr[i];
    }
    newarr[size-1]=newval;
    delete [] arr;
    arr = newarr;
}

template <class T>
void EArray<T>::display(){
    for(int i = 0; i < size; i++){
        cout << arr[i] << endl;
    }
}

int main(){
    EArray<int> A(6);
    A.setElement(0,34);
    A.setElement(1,544);
    A.setElement(2,32);
    A.setElement(3,324);
    A.setElement(4,24);
    A.display();
    A.addElement(3,12);
    A.display();
    A.eraseElement(4);
    A.display();
    A.push(32456);
    A.display();
}

Ответы [ 5 ]

12 голосов
/ 10 сентября 2010

Это не имеет ничего общего с шаблонами. Это просто проблема управления памятью. В конструкторе EArray вы никогда не инициализировали arr, поэтому по умолчанию он содержит недопустимый указатель.

Но затем в setElement вы использовали этот неверный указатель arr[i] = newval;, который должен вызвать SegFault.

Это должно быть исправлено путем добавления

arr = new T[size];

в конструкторе (результат: до, с segfault - после, нормально работает ).

(Кстати, на практике, пожалуйста, используйте std::vector.)

1 голос
/ 10 сентября 2010

Я все еще в этом. Но первая ошибка:

  • конструктор не выделяет, а только устанавливает размер
  • setElement получает доступ к полю, пока оно не выделено.

(похоже)

1 голос
/ 10 сентября 2010

Ваш конструктор EArray не инициализируется arr

добавить arr = new T[size]; после строки 24

Или измените его на:

template <class T>
EArray<T>::EArray(int l) : size(l), arr(new T[size]){
    size = l;
}

Вы должны также предоставить правильного агента копирования и оператора присваивания - или сделать их закрытыми, чтобы не допустить копирования вашего EArray.

0 голосов
/ 10 сентября 2010

Хорошо, стоит помнить, что вы указываете, что в вашей основной функции есть возврат int, и ничего не возвращаете.Это неправильно.

Ваша ошибка, однако, связана с тем, что вы устанавливаете размер массива в конструкторе, но фактически не выделяете для него место.Поэтому, когда вы пытаетесь установить первый элемент, он пытается установить его для нераспределенной памяти, и, таким образом, вы получаете segfault.

0 голосов
/ 10 сентября 2010

Ваш ctor НЕ выделяет память для элементов. И вы используете setElement, прежде чем вставлять элементы в объект. Таким образом, arr [i] в ​​setElement будет обращаться к нераспределенной памяти, а AV.

...