我正在尝试创建一种方法(delete_at
),该方法删除给定位置的节点,但出现分段错误(堆芯丢失)错误。奇怪的是,代码可以正常工作并有效地删除了我想要的节点,但是我不断收到该错误。错误出现在delete_at
中,其他方法也可以正常工作。
有人可以帮助我吗?
#include <iostream>
#include <stdlib.h>
using namespace std;
//each of the nodes of our list is a class
template <class T> class node {
private:
T data;
public:
node <T> *next;
node(): data(NULL), next(NULL) {}
node(T x): data(x), next(NULL) {}
T get_data () {
return (data);
}
};
template <class T> class list {
private:
node <T> *head, *p, *last;
public:
list(): head(NULL), p(NULL), last(NULL) {}
~list () {
node <T> *n;
for (p = head; p != NULL; p = p->next) {
n = p->next;
delete (p);
p = n;
}
delete (n);
cout << "list destroyed." << endl;
}
bool is_empty () {
return (head == NULL);
}
//inserts a node at the beginning of the list
void append (T x) {
p = new node <T> (x);
if (head == NULL) {
head = p;
last = head;
}
else {
p->next = head;
head = p;
}
}
//inserts a node at the end of the list
void push (T x) {
p = new node <T> (x);
if (head == NULL) {
head = p;
last = head;
}
else {
last->next = p;
last = p;
}
}
void pop () {
if (is_empty())
cout << "empty list.";
else if (head == last)
head = last = NULL;
else {
for (p = head; p->next != last; p = p->next);
delete (last);
last = p;
last->next = NULL;
}
}
void delete_at (int i) {
if (is_empty())
cout << "empty list.";
else if (i < size()) {
p = head;
if (i == 0) {
head = p->next;
delete (p);
}
else {
for (int j=0; j < i-1; j++)
p = p->next;
node <T> *tmp = p->next;
if (tmp->next != NULL) {
p->next = tmp->next;
}
else {
last = p;
last->next = NULL;
}
delete (tmp);
}
}
else
cout << "Invalid index." << endl;
}
void print () {
for (p = head; p != NULL; p = p->next)
cout << p->get_data() << " ";
cout << endl;
}
int size () {
int size = 0;
for (p = head; p != NULL; size++, p = p->next);
return (size);
}
T operator [] (int index) {
int i;
for (i=0, p = head; i < index; p = p->next, i++);
return (p->get_data());
}
};
int main () {
//initializing random seed
srand (time(NULL));
list <int> l;
cout << "Is the list empty? " << l.is_empty() << endl;
l.push(rand() % 100);
l.push(rand() % 100);
l.push(rand() % 100);
l.append(rand() % 100);
l.push (rand() % 100);
cout << "Is the list still empty? " << l.is_empty() << endl;
cout << "l[2] = " << l[2] << endl << endl;
cout << "size of the list: " << l.size() << endl;
l.print ();
l.pop ();
l.print();
l.delete_at (0);
l.print ();
l.delete_at (10);
return (0);
}
答案 0 :(得分:0)
您的代码中有许多错误。一次做一小步,并进行很多测试。
以下是一些问题和建议:
delete_at
函数中,先询问大小并没有多大意义,因为它会使列表重复两次。特别地,如果i
为0,则长度没有太大用处。delete_at(0)
以获得包含单个项目的列表,则您的代码将无法正确更新last
,也不会将head
重置为nullptr
。prev
初始化为nullptr
并前进直到达到所需的索引可能会容易得多。到那时,您知道是否必须更新头部(prev
仍然为零)和/或尾部(next
为零,以便删除该项目)。p
不应是成员变量。pop
中,如果列表包含单个项目,则不会删除该项目。last
未更新),很难在接下来的几步中预测是否出了问题。由于delete_at
中有2个main
呼叫点,因此您的问题也无法说明何时发生错误。并且提供您获得的输出将很有用。
我认为没有必要添加5个项目来获取崩溃,因此删除一些“更新”以查看崩溃是否仍会发生,可以更快地推断出实际状态。
我建议您进行一些单元测试。您应该在构造函数/析构函数中添加一个对象计数器或输出调用,以帮助检测缺失的删除。
要进行测试,您可以执行以下操作:
对于测试,您可以简单地使用data
的特定值进行测试,并检查您是否在某些时候具有预期的项目(并且您已经正确删除了适当数量的节点)。