似乎从Copy Constructor获取段错误?

时间:2012-07-31 07:01:10

标签: c++ segmentation-fault

我正在为一个简单的“Node”类编写一些C ++代码。这基本上是用于管理线性链表的类。我通常使用结构执行此操作,但我正在尝试更好地处理OOP和类。到目前为止,Node类的内容是(注意:String类是我的版本(修剪)典型的“字符串”类,它实现了一个复制构造函数,赋值重载,析构函数等。在测试中它有工作得很好,似乎完全独立):

class Node {
public:

    //Constructor
    //-----------

    Node() : next_(0) {} //inline (String constructor called)

    //Destructor
    //----------

    ~Node(); 

    //Copy Constructor
    //----------------

    Node(const Node &);    

    //Operator Overload: =
    //---------------------
    //In conjunction with copy constructor.  Protects Class.

    Node & operator=(const Node &);   

private:

    String relatedEntry_;
    Node * next_;
};

创建一个实例工作正常(即。Node node;)但是当我创建一个调用Copy Constructor的实例时,我最终会在程序的最后部分使用segfaults,因为它正在清理。使用链接列表的结构与类之间的区别对我来说有点诡计,我想我在这里缺少一些关键。以下是Default Constructor,Copy Constructor和Overloaded Assignment Operator的实现:

//Constructor inlined

//Destructor
Node::~Node()
{
    Node * curr = next_;
    while (curr) //cycle through LL and delete nodes
    {
        Node * temp = curr; //hold onto current
        curr = curr->next_; //increment one
        delete temp; //delete former current
    }
}


//Copy Constructor
Node::Node(const Node & cp)
{
    std::cout << "in CopyCon" << std::endl;
    relatedEntry_ = cp.relatedEntry_; //calls String class copy constructor/assignment overload
    Node * curr = cp.next_; //for clarity, for traversal
    while (curr) //copies related entry structure
    {
        Node * oldNext = next_;
        next_ = new Node;
        next_->next_ = oldNext; //'next' field (assign prior)
        next_->relatedEntry_ = curr->relatedEntry_; //String class copy
        curr = curr->next_; //increment
    }
}


//OO:  =
Node & Node::operator=(const Node & cp)
{
    std::cout << "in OO: =" << std::endl;
    if (this == &cp)
        return *this; //self assignment
    delete next_; //delete LL
    relatedEntry_ = cp.relatedEntry_; //String Class Assignment Overload
    Node * curr = cp.next_; //for clarity, for traversal
    while (curr)
    {
        Node * oldNext = next_; //hold onto old
        next_ = new Node; 
        next_->next_ = oldNext; //set next to old
        next_->relatedEntry_ = curr->relatedEntry_; //set this string to cp string
        curr = curr->next_; //increment
    }
    return *this;
}

请注意,使用重载分配函数似乎工作正常(没有segfaults),即使它实际上是相同的代码...我假设它与两个对象已经初始化之前的事实有关/ em>作业发生了吗?

//This seems to work ok
Node node1;
Node node2;
node2 = node1;

我已经在这个bug上呆了几个小时了,我得休息一下。我真的很感激任何洞察力。谢谢。

2 个答案:

答案 0 :(得分:1)

在复制构造函数循环中,您有以下行:

Node * oldNext = next_;

然而,在循环的第一轮中,next_的值可以是任何东西,很可能不是NULL。这意味着最后一个节点将具有非空指针。

在循环之前将其初始化为NULL,它应该可以正常工作。

答案 1 :(得分:1)

您将List和Node的概念混淆了。您应该编写一个List类来管理一系列节点。您的Node析构函数或多或少是List析构函数的外观,Node本身不需要析构函数。

特别错误的是你的Node析构函数在你写delete temp;时递归调用自身这会删除节点序列的其余部分,但是你的Node析构函数会循环并尝试再次删除它们。