2

私は現在リンクされたリスト構造を練習しており、そのアルゴリズムを使用してプログラムを作成しました。プログラムには、リンクされたリストのすべての要素を削除する再帰的な方法があります。ただし、その方法ではプログラムがクラッシュします。

void exit()
{
    Person* person = phead;
    exterminateStartingFrom(person);
}

void exterminateStartingFrom(Person* person)
{
    Person* nextperson;
    nextperson = person->getNext();
    if(nextperson){
        exterminateStartingFrom(nextperson);
    }
    delete person;
}

このメソッドは、ユーザーが終了したいときに実行されます。「phead」は人物リストの最初の要素を表します。示された問題は次のとおりです:二重解放または破損 (fasttop)

クラス Person は次のとおりです。

class Person {
private:
    std::string firstname;
    std::string lastname;
    int age;
    Person* next;

public:
    Person(std::string, std::string, int);
    void printDescription();
    void printFirstname();
    void printLastname();
    void printAge();
    void setNext(Person*);
    Person* getNext();


};

ありがとう。

4

3 に答える 3

1

あなたのリストは一方向リンクですか、それとも双方向ですか? 双方向リスト (次の要素だけでなく前の要素へのポインターも格納する) を使用している場合、デストラクタを呼び出すと、previousおよびnextフィールドで示される要素も削除できます。再帰が 1 レベル上に戻り、最後から 2 番目の要素を削除しようとすると、エラーが発生します。

于 2012-09-02T14:33:13.557 に答える
1

Person オブジェクトをどのように構築または削除しているかを知らずに判断するのは困難です。エラー メッセージは、同じエンティティを 2 回削除しているか、割り当てられていないものを削除していることを意味します。削除しようとしているアドレスを印刷して、同じアドレスが複数回削除されていないかどうかを確認してみてください。

また、再帰メソッドに渡すポインターが の場合も処理しますnill

于 2012-09-02T14:40:05.313 に答える
1

以下は私が取ったアプローチです。当然、実際の機能がわからないため、これは多少不自然です。また、初期グローバル変数で pHead を表し、範囲外の値で age を使用してリストの先頭を示しています。

リストの先頭には、特別なコンストラクターを使用します。

これを行うためのより良い方法はありますが、この迅速で汚い実装では、再帰中にバックアウトするときに、リストの先頭まで戻ったときに知っていたことを示す何かが必要でした。

#include <string>

class Person {
private:
    std::string firstname;
    std::string lastname;
    int age;
    Person* next;

public:
    Person (void);                           // constructor for the pHead
    ~Person (void);
    Person(std::string, std::string, int);   // standard constructor used
    std::string getFirstname(void) { return firstname; };
    std::string getLastname(void) { return lastname; }
    void setNext(Person *newNext) { next = newNext; }
    Person* getNext() { return next; }
    Person *addToListAt (Person *personList);
    void addToListAtEnd (Person *personList);
    void Person::insertListAfter (Person *personList);
    bool isHeadOfList (void);
};

Person pHead = Person();

// special constructor used to create the head to a linked list
Person::Person ()
{
    age = -1;
    next = 0;
}

// standard constructor used to create a list item.
Person::Person (std::string sFirstName, std::string sLastName, int myAge)
{
    if (myAge < 0) myAge = 0;
    firstname = sFirstName;
    lastname = sLastName;
    age = myAge;
    next = 0;
}

Person::~Person ()
{
    next = 0;
    age = 0;
}

void exterminateStartingFrom(Person* person)
{
    Person* nextPerson;
    nextPerson = person->getNext();
    if(nextPerson){
        exterminateStartingFrom(nextPerson);
    }

    if (! person->isHeadOfList())
        delete person;
}

Person *Person::addToListAt (Person *personList)
{
    Person* nextPerson;
    nextPerson = personList->getNext();
    personList->setNext (this);
    return nextPerson;
}

void Person::insertListAfter (Person *personList)
{
    Person* nextPerson;
    nextPerson = personList->getNext();
    personList->setNext (this);
    next = nextPerson;
}

void Person::addToListAtEnd (Person *personList)
{
    Person* nextperson;
    nextperson = personList->getNext();
    if(nextperson){
        addToListAtEnd (nextperson);
    } else {
        personList->setNext (this);
    }
}

bool Person::isHeadOfList (void)
{
    // we use a special age to represent the head of the list
    // the head does not contain any data except for point to first item
    // in the list.
    return (age < 0);
}

int main(int argc, char * argv[])
{
    Person *newPerson = new Person("first_1", "last_1", 11);
    newPerson->addToListAtEnd (&pHead);
    newPerson = new Person("first_2", "last_2", 22);
    newPerson->addToListAtEnd (&pHead);
    newPerson = new Person("first_3", "last_3", 33);
    newPerson->addToListAtEnd (&pHead);

    Person *itemPerson = pHead.getNext();
    newPerson = new Person("first_11", "last_11", 12);

    newPerson->insertListAfter (itemPerson);

    exterminateStartingFrom(&pHead);
    return 0;
}
于 2012-09-02T16:16:30.710 に答える