简体   繁体   English

单链表-分段错误

[英]Singly linked list - Segmentation fault

First, sorry for the long code. 首先,对于长代码感到抱歉。 I did my best to trim it as small as possible. 我已尽力将其修剪得尽可能小。 I'm getting segmentation fault when i want to add a new element ( void SLList::pushBack(const Data &rDATA) ) to my singly linked list (in SLList.hxx). 当我想向我的单链接列表(在SLList.hxx中)添加一个新元素( void SLList::pushBack(const Data &rDATA) )时出现分段错误。 The segmentation fault caused by 0xbaadf00d value. 由0xbaadf00d值引起的分段错误。 ........................................................................................................ ................................................... ................................................... ....

IniFile.h IniFile.h

#include "Section.h"
class IniFile
{
  public:
    IniFile() :
    void addSection();

  private:
    SLList<Section> mContent;
};

IniFile.cpp IniFile.cpp

#include "IniFile.h"
IniFile::IniFile() :
   mContent() {}

void IniFile::addSection() // This is the only one method what i call
{
   mContent.pushBack(Section());
}

Section.h h节

#include "Pair.hxx"
#include "SLList.hxx"
class Section
{
  public:
    Section();

  private:
    SLList<Pair<std::string, std::string>> mKeyValuePairs;
};

Section.cpp Section.cpp

#include "Section.h"
Section::Section() :
    mKeyValuePairs() {}

SLList.hxx SLList.hxx

template <typename Data>
class SLList
{
  public:
    class Node
    {
      public:
        Node(const Data &rDATA, Node *const pNEXT = nullptr) :
            mData(rDATA),
            mNext(pNEXT) {}

        Node(const Node &rRHS)
        {
            mData = rRHS.mData;
            *mNext = *rRHS.mNext;
        }

        ~Node()
        {
            delete mNext;
        }

        Node &operator=(const Node &rRHS)
        {
            if (&rRHS == this)
                return *this;
            mData = rRHS.mData;
            *mNext = *rRHS.mNext;
            return *this;
        }

      private:
        void setNext(Node *const pNext)
        {
            mNext = pNext;
        }

        friend void SLList<Data>::pushBack(const Data &rDATA);

      private:
        Data mData;
        Node *mNext;
    };

    SLList() :
        mHead(nullptr),
        mTail(nullptr) {}


    SLList(const SLList &rRHS)
    {
        *mHead = *rRHS.mHead;
        *mTail = *rRHS.mTail;
    }

    SLList &operator=(const SLList &rRHS)
    {
        if (&rRHS == this)
            return *this;
        *mHead = *rRHS.mHead;
        *mTail = *rRHS.mTail;
        return *this;
    }

    ~SLList()
    {
        clear();
    }

    void clear()
    {
        delete mHead;
    }

    void pushBack(const Data &rDATA)
    {
        Node *pNode = new Node(rDATA, nullptr); // I get segmentation fault at this point
        if (!mTail)
        {
            mHead = pNode;
            mTail = pNode;
        }
        else
        {
            mTail->setNext(pNode);
            mTail = pNode;
        }
    }

  private:
    Node *mHead;
    Node *mTail;
};

Pair.hxx 对.hxx

template <typename T1, typename T2>
class Pair
{
  public:
    Pair(const T1 &rFIRST, const T2 &rSECOND) :
        mFirst(rFIRST),
        mSecond(rSECOND) {}

  private:
    T1 mFirst;
    T2 mSecond;
};

SLList 's copy constructor and assignment operator are wrong in terms of Node* pointer management. Node*指针管理而言, SLList的副本构造函数和赋值运算符是错误的。

Also, Node 's destructor shouldn't destroy the next Node object in the list. 另外, Node的析构函数不应破坏列表中的下一个Node对象。 Not only is a recursive destructor bad for long lists, but also think of in the future if you ever want to remove a single Node without clearing the whole list. 递归析构函数不仅不利于长列表,而且如果您想在不清除整个列表的情况下删除单个Node ,将来还会考虑。 Your clear() method should directly iterate the list deleting Node objects one at a time without using recursion. 您的clear()方法应直接迭代一次删除Node对象的列表,而不使用递归。

Try something more like this: 尝试更多类似这样的方法:

#include <utility>
template <typename Data>
class SLList
{
public:
    class Node
    {
    public:
        Node(const Data &rDATA, Node *const pNEXT = nullptr)
            : mData(rDATA), mNext(pNEXT)
        {
        }

        Node(const Node &rSRC)
            : mData(rSRC.mData), mNext(nullptr)
        {
        }

        Node &operator=(const Node &rRHS)
        {
            if (&rRHS != this)
                mData = rRHS.mData;
            return *this;
        }

    private:
        Data mData;
        Node *mNext;

        friend class SLList<Data>;
    };

    SLList()
        : mHead(nullptr), mTail(nullptr)
    {
    }

    SLList(const SLList &rSRC)
        : mHead(nullptr), mTail(nullptr)
    {
        Node *pNode = rSRC.mHead;
        while (pNode)
        {
            pushBack(pNode->mData);
            pNode = pNode->mNext;
        } 
    }

    SLList &operator=(const SLList &rRHS)
    {
        if (&rRHS != this)
        {
            SLList temp(rRHS);
            std::swap(mHead, temp.mHead);
            std::swap(mTail, temp.mTail);
        }
        return *this;
    }

    ~SLList()
    {
        clear();
    }

    void clear()
    {
        Node *pNode = mHead;
        mHead = mTail = nullptr;
        while (pNode)
        {
            Node *pNext = pNode->mNext;
            delete pNode;
            pNode = pNext;
        }
    }

    void pushBack(const Data &rDATA)
    {
        Node *pNode = new Node(rDATA);
        if (!mHead) mHead = pNode;
        if (mTail) mTail->mNext = pNode;
        mTail = pNode;
    }

private:
    Node *mHead;
    Node *mTail;
};

With that said, what you really should do is use std::list (or std::forward_list ) and std::pair instead. 话虽如此,您真正应该做的是使用std::list (或std::forward_list )和std::pair代替。 There is no benefit to "reinventing the wheel" at all: “重新发明轮子”根本没有任何好处:

#include "Section.h"
#include <list>
class IniFile
{
public:
    void addSection();
private:
    std::list<Section> mContent;
};

#include "IniFile.h"
void IniFile::addSection()
{
    mContent.push_back(Section());
}

#include <pair>
#include <list>
#include <string>
class Section
{
private:
    std::list<std::pair<std::string, std::string>> mKeyValuePairs;
};

#include <list>
template <typename Data>
class SLList
{
public:
    void clear()
    {
        mList.clear();
    }

    void pushBack(const Data &rDATA)
    {
        mList.push_back(rDATA);
    }

private:
    std::list<Data> mList;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM