0

我在 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;
    }
 };

当我删除程序上方的标记线时,没有响应。这是我的节点构造函数:

#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;
    }
};

我的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 感谢您的阅读,请尽快提供帮助,如果您需要我提供更多信息,请发表评论。

4

3 回答 3

2

编辑:您的程序存在许多问题,但可能导致您崩溃的原因是:您的Add-function 无法正常工作。它应该是这样的:

if(first==NULL) {
    first = new Node<T>(NULL, value);
    last = first;
} else {
    last = new Node<T>(last, value);
}
length++;

否则,它将无法正确插入第二个元素。为什么?使用您的原始代码,在第一次添加之后,您last仍然是 NULL,因为else. 因此,在第二次添加时,您将 last 设置为new Node<T>(NULL, value). 因此,它不会分配第一个元素的next指针。而且你的清单会不一致。

除此之外,还有双重释放、stringObject 类中不必要的堆分配、所有权问题等。再举一个例子:你的List析构函数会由于双重释放而导致堆损坏。delete first由于delete nextin的析构函数,调用将删除所有节点Node,只要列表一致。然后你调用delete last,但是那个对象已经被释放了。这会破坏程序的内存管理,也可能导致程序退出时崩溃。

于 2013-01-21T23:22:33.250 回答
2

这个功能对你来说是否正确?

它说GetPrev,但它实际上得到了next

Node* GetPrev() {
    return next;
}
于 2013-01-21T23:09:59.917 回答
1

我发现如果我在Node构造函数中注释掉这一行代码编译:

if (next != NULL) {
    // next->next = this;
    prev = next;
}

编辑1:

我还意识到你在Node课堂上是这样做的:

private:
    Node* next;
    Node* prev;
    T value;

由于这些对象是在Node类中声明的,因此它们此时是不完整的类型。我设法将这个问题复制到一个像这样的简单问题:

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类中的指针是建立在不完整的类型之上的;并从他们那里访问数据正在查看不属于您的内存,因此会崩溃。

于 2013-01-21T23:43:17.117 回答