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

この関数はあなたにとって正しいと思われますか?

と書いてありますGetPrevが、実際に取得していnextます。

Node* GetPrev() {
    return next;
}
于 2013-01-21T23:09:59.917 に答える
2

編集:プログラムには多くの問題がありますが、クラッシュの原因となる可能性があります:Add関数が正しく機能していません。次のようになります。

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

そうしないと、2番目の要素が正しく挿入されません。なんで?元のコードでは、最初の追加後も、lastが原因でNULLのままになりますelse。したがって、2番目の追加では、最後をに設定しnew Node<T>(NULL, value)ます。したがって、最初の要素のnextポインタは割り当てられません。そして、あなたのリストは一貫性がなくなります。

それとは別に、ダブルフリー、stringObjectクラスのフィールドの不要なヒープ割り当て、所有権の問題などがあります。もう1つの例を挙げればList、デストラクタはダブルフリーのためにヒープの破損を引き起こします。リストに一貫性がある限り、を呼び出すと、のデストラクタdelete firstが原因ですべてのノードが削除されます。次に、を呼び出しますが、そのオブジェクトはすでに解放されています。これにより、プログラムのメモリ管理が破損し、プログラムの終了時にクラッシュが発生する可能性があります。delete nextNodedelete last

于 2013-01-21T23:22:33.250 に答える
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 に答える