我已经实现了一个List(与标准c ++列表不同),这是用于练习。 问题是在调整列表大小后,我得到了分段错误。 当我得到seg时,我已经标记了linke。错,我不知道原因。
调整大小方法的目的是调整列表的大小:假设我有一个2个整数的列表,如果我将其调整为5,我将得到其他3个元素,全部初始化为零。 如果我有一个包含4个元素的列表,我将其调整为2,将减少2个元素。 如果我有一个int列表l,l [0]是列表的第一个对象,l [1]是第二个... 所以当我试图调整列表大小时,我崩溃了,正是在我标记的行中。
#include <iostream>
#include <cassert>
using namespace std;
template<class T>
class List
{
public:
List<T>();
~List<T>();
protected:
List<T> (T info);
public:
int size();
void resize(int length);
void add(T info,int i);
void push(T info);
T pop();
void remove(int i);
T extract(int i);
T get(int i);
friend ostream& operator<< (ostream& out, List<T>& l)
{
List<T>* ptr=l.next;
if(l.info==NULL)
{
while(ptr!=&l)
{
out << *(ptr->info) << "\t";
ptr=ptr->next;
}
}
else
{
out<< *(l.info) <<"\t";
}
return out;
}
friend istream& operator>> (istream& in,List<T>& l)
{
in >> (*l.info);
return in;
}
bool operator== (List<T>& r)
{
bool result=true;
List<T>* p1,*p2;
p1=this;
p2=&r;
assert((p1->info==NULL && p2->info==NULL)||(p1->info!=NULL && p2->info!=NULL));
if(p1->info==NULL)
{
p1=p1->next;
p2=p2->next;
result=(p1->length == p2->length);
while(result && p1!=this)
{
result=(*(p1->info)==*(p2->info));
p1=p1->next;
p2=p2->next;
}
}
else
{
result=(*(p1->info)==*(p2->info));
}
return result;
}
List<T>& operator+= (List<T>& l)
{
List<T>* ptr;
ptr=l.next;
while(ptr!=&l)
{
this->push(*(ptr->info));
ptr=ptr->next;
}
return *this;
}
List<T>& operator[] (int i)
{
List<T>* ptr;
ptr=this;
assert(i<length);
for(int j=0;j<=i;j++)
ptr=ptr->next;
return *ptr;
}
private:
T *info;
List <T>* next;
List <T>* prev;
int length;
};
template <class T>
List<T>::List ()
{
info=NULL;
next=this;
prev=this;
length=0;
}
template<class T>
List<T>::List (T info)
{
next=this;
prev=this;
this->info=new T();
*(this->info)=info;
}
template<class T>
List<T>::~List()
{
List<T>* ptr, * temp;
ptr=this->next;
if(this->info==NULL)
{
while(ptr!=this)
{
delete ptr->info;
temp=ptr;
ptr=ptr->next;
delete temp;
}
}
}
template<class T>
int List<T>::size()
{
return length;
}
template<class T>
void List<T>::resize(int length)
{
assert(length>=0);
if(this->length<length)
{
for(int i=this->length;i<length;i++)
push(0);
}
else
{
for(int i=length;i<this->length;i++)
extract(this->length-1); // here I call exctract, extract calls
} // remove, remove calls get
}
template<class T>
void List<T>::add(T info,int i)
{
List<T>* ptr,*t1,*t2;
length++;
ptr=&((*this)[i]);
t1=ptr->prev;
t2=ptr;
ptr=new List<T>(info);
t1->next=ptr;
ptr->prev=t1;
t2->prev=ptr;
ptr->next=t2;
}
template<class T>
void List<T>::push(T info)
{
add(info,length-1);
}
template<class T>
void List<T>::remove(int i)
{
List<T>* ptr,*t1,*t2;
ptr=&((*this)[i]);
t1=ptr->prev;
t2=ptr->next;
delete ptr;
t1->next=t2;
t2->prev=t1;
length--;
}
template<class T>
T List<T>::extract(int i)
{
T temp=this->get(i);
remove(i);
return temp;
}
template<class T>
T List<T>::get(int i)
{
assert(i<length);
return *(this[i].info); // here i have seg. fault !!!!!!!!!!
} // I cannot figure why ...
template<class T>
T List<T>::pop()
{
return extract(length-1);
}
int main(int argc, char **argv)
{
List<int> l;
l.resize(3);
for(int i=0;i<3;i++)
cin>>l[i];
l.resize(2);
cout<<l<<endl;
return 0;
}
我希望这不是一个过于戏剧化的文档,提前感谢谁会阅读并试图帮助我。
答案 0 :(得分:1)
在resize
中,for
循环更改i
并将其与this->length
进行比较,但push
和extract
都会更改{{1}所以你要将两个变化的变量相互比较。
这可能是更好的方法:
this->length