2010-09-10 101 views
0

我在可擴展數組上寫了我的第一個C++模板代碼,並且出現了分段錯誤!經過一小時的調試,我意識到我需要幫助。我認爲構造函數或析構函數有問題但不確定。分段錯誤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(); 
} 
+6

你從哪裏得到分段錯誤?你是否將一個調試器附加到你的程序中以查看它崩潰時的錯誤?你是否將代碼減少到了重現問題所需的最小值? – 2010-09-10 18:04:48

+0

詹姆斯的問題是每當試圖分析段錯誤時都應該回答的問題。 +1。 – CanSpice 2010-09-10 18:07:18

+0

我想我必須學習使用調試器。 – zubinmehta 2010-09-10 18:26:55

回答

12

它無關的模板。這只是一個內存管理問題。在EArray的構造函數中,你從未初始化過arr,所以默認情況下它包含一些無效指針。

但是,在setElement中,您使用了應該導致SegFault的無效指針arr[i] = newval;。 (: - after, running finebefore, with segfault結果)

應該在構造函數中添加

arr = new T[size]; 

是可以解決的。

(順便說一句,在實踐中,請使用std::vector。)

+0

是的,我寫這個只是爲了理解機制。我會使用st :: vector來使用。感謝你的回答。 – zubinmehta 2010-09-10 18:21:12

0

你的構造函數不爲元素分配內存。 在將元素推入對象之前,您正在使用setElement。 因此,setElement中的arr [i]將訪問未分配的內存和AV。

1

你EArray構造函數不初始化arr

線24

後添加arr = new T[size];或更改爲:

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

你應該提供一個正確副本construtor和賦值運算符,以及 - 或使他們私密,不讓你的EArray被複制。

0

嗯,需要記住的一件事是,你指定在你的主函數中有一個int的返回,然後不返回任何東西。這是錯誤的。

但是,您的錯誤是因爲您在構造函數中設置了數組的大小,但實際上並未爲其分配空間。所以當你嘗試設置第一個元素時,它會嘗試將其設置爲未分配的內存,因此最終會出現段錯誤。

+2

你的第一點是不正確的。如果你沒有返回任何東西,'main'允許有一個隱含的'return 0;'結尾。 – 2010-09-10 18:46:54

1

我還在。但是第一個錯誤是:

  • 構造不分配,但是隻設置大小
  • setElement並進入領域,而沒有分配它。

(這似乎是它)