我在c ++中创建了这个链表类,它运行正常,除非我运行它后程序没有响应。我找到导致问题的线但我不知道为什么。即使我以不同的方式输入它,它仍然会做同样的事情。
这是我的列表类:
#include <string>
template<class T>
class List : public Object{
private:
Node<T>* first;
Node<T>* last;
int length;
public:
List() : Object(new std::string("List")) {
first = NULL;
last = NULL;
length = 0;
}
~List() {
delete first;
delete last;
}
void Add(T value) {
if(first==NULL)
first = new Node<T>(NULL, value);
else if(last==NULL)
---->last = new Node<T>(first, value);<-----
else
last = new Node<T>(last, value);
length++;
}
T Remove(T value) {
Node<T>* temp = first;
while(temp!=NULL) {
if(temp->GetValue()==value) {
temp->GetPrev()->SetNext(temp->GetNext());
temp->GetNext()->SetPrev(temp->GetPrev());
delete temp;
length--;
return value;
}
temp = temp->GetNext();
}
return 0;
}
T Get(int index) {
Node<T>* temp = first;
int i = 0;
while(temp!=NULL) {
if(i==index)
return temp->GetValue();
i++;
temp = temp->GetNext();
}
return 0;
}
};
当我删除程序上方标记的行时,反复无响应。这是我的Node构造函数:
#include <string>
template<class T>
class Node : public Object{
private:
Node* next;
Node* prev;
T value;
public:
Node(Node* prev, T value) : Object(new std::string("Node")){
if(prev!=NULL) {
prev->next = this;
this->prev = next;
}
next = NULL;
this->value = value;
}
~Node() {
delete next;
}
T GetValue() {
return value;
}
Node* GetNext() {
return next;
}
Node* GetPrev() {
return next;
}
};
我的对象类:
#include <string>
class Object {
private:
std::string* type;
public:
Object() {
type = new std::string("Object");
}
Object(std::string* type) {
this->type = type;
}
~Object() {
delete type;
}
std::string* GetType() {
return type;
}
};
my Test.cpp
#include <iostream>
#include <string>
#include "Object.h"
#include "Node.h"
#include "List.h"
using namespace std;
int main () {
List<int> l;
l.Add(5);
l.Add(93);
l.Add(17);
l.Add(7789);
l.Add(60);
cout << "node 4 is:" << l.Get(3) << endl;
return 0;
}
错误图片http://i50.tinypic.com/2mw5phi.png 感谢阅读,请尽快帮助,如果您需要我提供更多信息,请发表评论。
答案 0 :(得分:2)
编辑:您的程序存在许多问题,但可能导致崩溃的原因是:您的Add
- 功能无法正常运行。它应该是这样的:
if(first==NULL) {
first = new Node<T>(NULL, value);
last = first;
} else {
last = new Node<T>(last, value);
}
length++;
否则,它将无法正确插入第二个元素。为什么?使用原始代码,在第一次添加后,由于last
,您的else
仍为NULL。因此,在第二次添加时,您将最后一次设置为new Node<T>(NULL, value)
。因此,它不会分配第一个元素的next
指针。而且你的清单会不一致。
除此之外,还有双重释放,Object类中string
字段的不必要的堆分配,所有权问题等。再举几个例子:你的List
析构函数将会由于双重释放导致堆损坏。只要列表一致,调用delete first
将删除由delete next
的析构函数中的Node
引起的所有节点。然后你调用delete last
,但该对象已被释放。这将破坏程序的内存管理,也可能导致程序退出时崩溃。
答案 1 :(得分:1)
我发现如果我在Node
构造函数中注释掉这一行代码编译:
if (next != NULL) {
// next->next = this;
prev = next;
}
修改1:
我也意识到你在Node
课程中这样做了:
private:
Node* next;
Node* prev;
T value;
由于这些对象是在Node
类中声明的,因此它们目前是不完整的类型。我设法将这个问题复制到一个简单的问题,如this:
template <class T>
struct S {
S* s = new S();
~S() { delete s; }
};
int main() {
S<int> s; // Segmentation fault (core dumped) ./test > .stdout
}
这会导致崩溃,因为S
本身就是一个不完整的类型。
我得到了与我的代码相同的分段错误。我很确定它是因为Node
类中的指针是基于不完整的类型构建的;并且从他们那里访问数据会查找不属于您的内存,从而导致崩溃。