2010-09-10 4 views
0

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

Код находится на пасте, готовом к компиляции. 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(); 
} 
+6

Где вы получите ошибку сегментации? Вы подключили отладчик к своей программе, чтобы узнать, что не так, когда он сработает? Вы уменьшили код до минимума, необходимого для воспроизведения проблемы? –

+0

Вопросы Джеймса - это те, на которые всегда нужно отвечать, пытаясь проанализировать segfault. +1. – CanSpice

+0

Думаю, мне нужно научиться использовать отладчик. – zubinmehta

ответ

12

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

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

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

arr = new T[size]; 

в конструктор (результат: before, with segfault - after, running fine).

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

+0

Да, я написал это, чтобы понять механику. Я использовал бы вектор st :: для использования. Спасибо за ответ. – zubinmehta

0

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

1

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

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

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

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

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

0

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

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

+2

Ваш первый пункт неверен. 'main' разрешено иметь подразумеваемый' return 0; ', прикрепленный в конце, если вы ничего не возвращаете. –

1

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

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

(что, кажется, она)

Смежные вопросы