递归方法C ++

时间:2012-09-02 14:27:56

标签: c++ pointers methods recursion double-free

我正在练习链表结构,我已经使用该算法编写了一个程序。在程序中有一个递归方法来删除链表的每个元素。但是,程序在该方法中崩溃。

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();


};

感谢。

3 个答案:

答案 0 :(得分:1)

您的列表是单向链接还是双向链接?如果你有一个双向列表(你不仅将指针存储到下一个元素而且还存储到前一个元素),并且你调用析构函数,你也可以删除由previous和{{1}指示的元素。 }字段。当递归返回一级并且您想要删除倒数第二个元素时,您会收到错误。

答案 1 :(得分:1)

如果不知道如何构建或删除Person对象,很难说清楚。您的错误消息意味着您要删除相同的实体两次,或者您正在删除未分配的内容。可能会尝试打印您要删除的地址,以便检查是否有同一地址被删除多次?

同时处理传递给递归方法的指针为nill的情况。

答案 2 :(得分:1)

以下是我采取的方法。当然,这有点人为,因为我不知道你的实际功能。我也用一个初始的全局变量表示pHead,并使用超出范围值的年龄来表示列表的头部。

对于列表的头部,我使用了一个特殊的构造函数。

有更好的方法可以做到这一点,但是在这个快速而又脏的实现中,我需要一些东西来指示在递归期间退出时我知道当我一直支持到列表的头部时。

#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;
}
相关问题