2010-09-10 73 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并进入领域,而没有分配它。

(这似乎是它)