首先,抱歉长代码。我尽力把它修剪得尽可能小。
当我想在我的单链表(在SLList.hxx中)添加一个新元素(void SLList::pushBack(const Data &rDATA)
)时,我遇到了分段错误。由0xbaadf00d值引起的分段错误。
.................................................. .................................................. ....
IniFile.h
#include "Section.h"
class IniFile
{
public:
IniFile() :
void addSection();
private:
SLList<Section> mContent;
};
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
#include "Pair.hxx"
#include "SLList.hxx"
class Section
{
public:
Section();
private:
SLList<Pair<std::string, std::string>> mKeyValuePairs;
};
Section.cpp
#include "Section.h"
Section::Section() :
mKeyValuePairs() {}
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
template <typename T1, typename T2>
class Pair
{
public:
Pair(const T1 &rFIRST, const T2 &rSECOND) :
mFirst(rFIRST),
mSecond(rSECOND) {}
private:
T1 mFirst;
T2 mSecond;
};
答案 0 :(得分:0)
SLList
的复制构造函数和赋值运算符在Node*
指针管理方面是错误的。
此外,Node
的析构函数不应销毁列表中的下一个Node
对象。递归析构函数不仅对长列表不利,而且如果您想要在不清除整个列表的情况下删除单个Node
,也会考虑将来。您的clear()
方法应该直接迭代删除Node
个对象的列表,而不使用递归。
尝试更像这样的事情:
#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;
};
话虽如此,真正应该做的是使用std::list
(或std::forward_list
)和std::pair
代替。根本没有“重新发明轮子”的好处:
#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;
};