_Block_Type_Is_Valid(pHead-> nBlockUse)递归删除链表后出错

时间:2014-12-12 04:50:55

标签: c++ pointers recursion visual-studio-2013 linked-list

我已经成功实现了一个递归PrintList方法,所以我不明白为什么递归析构函数不能工作:

//recursively deleting nodes in a doubly linked list
LinkedList::~LinkedList()
{
    if (Head == 0) //base case
    {
        Tail = 0; //fixing the dangling Tail pointer doesn't seem to fix the error...
        return;
    }

    else
    {
        Node* temp = Head;
        Head = Head->getNext();
        cout << "deleting " << temp->getNumber() << endl;
        delete temp;
        delete this;
    }
}

调试时,我在调用LinkedList析构函数之后得到_Block_Type_Is_Valid(pHead-&gt; nBlockUse)错误,就在程序完成之前&#34;很好地&#34;。这已过去&#34;返回0;&#34;在main.cpp中,我逐步完成了上面显示的析构函数代码,实际上析构函数给了我所有正确的测试消息并按预期工作。

更令人沮丧的是,我无法找到导致此错误的原因:我试图超越&#34;除了LinkedList析构函数代码之外,我从VS获得了消息:&#34; Source Not Available:此模块的调试信息中缺少源信息&#34;。我在想悬挂的Tail指针(在析构函数执行后指向随机内存)可能是个问题,所以我设置了#34; Tail = 0;&#34;在从基础案例返回之前,但似乎并没有起作用。

我能够抑制此错误的唯一方法是:

  1. 构建一个LinkedList,然后简单地结束程序而不向其中添加任何节点(删除空的LinkedList没问题),或者

  2. 使我的LinkedList在main中动态分配,并在不手动删除它的情况下结束程序(跳过整个LinkedList析构函数)

  3. 这是什么问题?救命!!


    更新:我出色的CS教授指出了我的问题:

    &#34;当析构函数退出并尝试自动重新分配节点时,它已被delete this语句销毁。 当使用delete关键字时,它会启动析构函数,然后释放内存。&#34;

    所以喜欢@ 0x499602D2指出,&#34;删除这个&#34;是有问题的行,但它与我的LinkedList是否已被新建,然后在编译时删除或静态创建然后自动销毁无关。基本上它是由析构函数的行为引起的。

    解决方案是:改变&#34;删除它;&#34; to&#34; this-&gt;〜LinkedList();&#34;

    仅限&#34; this-&gt; ~RubinList();&#34;我可以在没有真正&#34;删除&#34;的情况下对析构函数进行递归调用。调用对象;相反,当析构函数退出并自动解除分配时,它将被销毁,避免再次删除它的错误。





    更多细节: 这是我对Node的实现(双重链接)。它源自单链接的BaseNode类:

    //Specification file for BaseNode class
    #ifndef BASENODE_H
    #define BASENODE_H
    #include <iostream>
    
    class BaseNode
    {
    protected:
        char * name;
        int number;
        BaseNode * next;
    
    public:
        //default constructor
        BaseNode();
        //overloaded constructor
        BaseNode(const char *, int);
    
        //destructor
        ~BaseNode() {
            std::cout << "name is: " << name << '\n';
            delete[] name;
        }
    
        //getter functions
        char * getName() const { return name; }
        int getNumber() const { return number; }
        BaseNode* getNext() { return next; }
    
        //setter functions
        void setNumber(int num){ number = num; };
        void setNext(BaseNode* ptr) { next = ptr; }
    };
    #endif
    
    //Implementation file for BaseNode class
    #ifdef _MSC_VER
    #define _CRT_SECURE_NO_WARNINGS
    #endif
    #include <cstring>
    #include "BaseNode.h"
    
    
    //default constructor
    BaseNode::BaseNode()
    {
        name = 0;
        number = 0;
        next = 0;
    }
    
    //overloaded constructor
    BaseNode::BaseNode(const char * str, int num)
    {
        roman = new char[strlen(str) + 1]; //set aside one more character for null terminator
        strcpy(name, str);
        number = num;
    }
    

    然后我的Node类继承了BaseNode类:

    #ifndef Node_H
    #define Node_H
    
    #include "BaseNode.h" //include the base class for inheritance to work
    
    class Node : public BaseNode
    {
    protected:
        Node * prev;
        Node * next;
    
    public:
        Node() : BaseNode()
        { prev = next = 0; }
    
        Node(const char * namestr, int num) : BaseNode(namestr, num)
        { prev = next = 0; }
    
        //empty destructor; the BaseNode destructor automatically gets called from here and does the job
        ~Node() { }
    
        //getter functions and setter functions are all inherited from BaseNode, except that....
        //the BaseNode version of getNext and setNext won't work for our Node class
    
        Node* getNext() const { return next; }
        void setnext(Node* pointer) { next = pointer; }
    
        Node* getPrev() const { return prev; }
        void setPrev(Node* pointer) { prev = pointer; }
    
    };
    #endif
    

0 个答案:

没有答案