为什么我在catch2测试中得到这个SIGSEGV信号? 我目前正在学习C++,作为一个练习,我一直在尝试实现链表数据结构。我正在Catch2中为它编写测试,我一直收到SIGSEGV信号,我不知道为什么

为什么我在catch2测试中得到这个SIGSEGV信号? 我目前正在学习C++,作为一个练习,我一直在尝试实现链表数据结构。我正在Catch2中为它编写测试,我一直收到SIGSEGV信号,我不知道为什么,c++,templates,segmentation-fault,catch2,C++,Templates,Segmentation Fault,Catch2,这是我的链接列表头文件: 布拉格语一次 命名空间数据结构{ 样板 类链接列表{ 私人: 类节点 { 私人: T m_数据; Node*m_next; 公众: 节点数据; ~Node; Node*get_next; 无效集_nextT数据; 无效集合_nextNode*next; 得不到数据; 无效集合数据; }; 节点*m_头; 国际货币单位大小; 公众: /** *@brief构造一个新的链表对象 * */ 链接列表; LinkedListconst LinkedList和其他; Linke

这是我的链接列表头文件:

布拉格语一次 命名空间数据结构{ 样板 类链接列表{ 私人: 类节点 { 私人: T m_数据; Node*m_next; 公众: 节点数据; ~Node; Node*get_next; 无效集_nextT数据; 无效集合_nextNode*next; 得不到数据; 无效集合数据; }; 节点*m_头; 国际货币单位大小; 公众: /** *@brief构造一个新的链表对象 * */ 链接列表; LinkedListconst LinkedList和其他; LinkedList&operator=const LinkedList&other; /** *@brief销毁链表对象 * */ ~LinkedList; /** *@brief获取列表的大小 * *@return int */ 整数大小; /** *@brief如果列表为空,则返回true * *@return-true *@return-false */ 布尔是空的; /** *@brief获取列表中的第一个值 * *@return T */ T第一; /** *@brief从列表中给定的索引中获取值 * *@param索引 *@return T */ T-getint指数; /** *@brief从列表中删除给定索引中的值 * *@param索引 *@return T删除的值 */ T去除指数; /** *@brief将给定索引处的值设置为给定值 * *@param索引 *@param val */ void setint索引,T val; /** *@brief在列表中的给定索引处插入给定值 * *@param索引 *@param val */ 无效插入指数,T值; /** *@brief将给定值追加到列表的末尾 * *@param val */ 无效附属物; }; } 包括模板/链接列表.tcc 以下是我的链表实现文件:

包括 使用名称空间数据结构; pragma区域节点实现 样板 LinkedList::Node::节点集数据{ m_data=数据; m_next=NULL; } 样板 LinkedList::Node::~Node{ //不执行任何操作。删除成员m_next不在此类范围内。 } 样板 typename LinkedList::Node*LinkedList::Node::get\u next{ 下一步返回m_; } 样板 void LinkedList::Node::set_nextT数据{ LinkedList::Node*tmp=新建LinkedList::Nodedata; //不要删除上一个下一个对象。这是由链表类处理的 m_next=tmp; } 样板 void LinkedList::Node::set_nextLinkedList::Node*下一步{ //不要删除上一个下一个对象。这是由链表类处理的 m_next=next; } 样板 T LinkedList::Node::获取_数据{ 返回m_数据; } 样板 void LinkedList::Node::set_dataT data{ m_data=数据; } 布拉格端区 pragma区域链表的实现 样板 LinkedList::LinkedList{ m_大小=0; m_头=空; } 样板 LinkedList::~LinkedList{ typename LinkedList::Node*currentNode=m_头; 而currentNode!=NULL { typename LinkedList::Node*tmp=currentNode->get\u next; 删除当前节点; currentNode=tmp; } } 样板 int LinkedList::size{ 返回m_大小; } 样板 bool LinkedList::是否为空{ 返回m_size==0; } 样板 T LinkedList::first{ 如果m_head==NULL { 抛出列表为空; } 返回m_head->get_data; } 样板 T LinkedList::getint索引{ 如果索引>=m|U大小|索引<0 { 将索引抛出边界; } typename LinkedList::Node*currentNode=m_头; int currentIndex=0; 而currentIndexget_next; currentIndex++; } 返回currentNode->get_数据; } 样板 T LinkedList::删除索引{ 如果索引>=m|U大小|索引<0 { 将索引抛出边界; } typename LinkedList::Node*prevNode=NULL; typename LinkedList::Node*currentNode=m_头; int currentIndex=0; 而currentIndexget_next; currentIndex++; } T被移除; //删除第一个元素时的特殊情况 如果prevNode==NULL{ m_head=currentNode->get_next; 已删除\u val=currentNode->get\u数据; 删除当前节点; } 否则{ prevNode->set_nextcurrentNode->get_next; 已删除\u val=currentNode->get\u数据; 删除当前节点; } m_尺寸-; 返回已删除的值; } 样板 void LinkedList::setint索引,T val{ 如果索引>=m|U大小|索引<0 { 将索引抛出边界; } typename LinkedList::Node*currentNode=m_头; int currentIndex=0; 而currentIndexget_next; currentIndex++; } 当前节点->设置数据值; } 样板 void LinkedList::插入索引,T val{ 如果索引>=m|U大小|索引<0 { 将索引抛出边界; } typename LinkedList::Node*prevNode=NULL; typename LinkedList::Node*currentNode=m_头; typename LinkedList::Node*newNode=newlinkedlist::Nodeval; int currentIndex=0; 而currentIndexget_next; currentIndex++; } //插入第一个元素时的特殊情况 如果prevNode==NULL{ m_头=新节点; 新建节点->设置下一个当前节点; } //所有其他情况都应包括在本报告中 否则{ prevNode->set_nextNode; 新建节点->设置下一个当前节点; } m_size++; } 样板 void LinkedList::appendT val{ 如果m_size==0和m_head==NULL{ m_head=newlinkedlist::Nodeval; } typename LinkedList::Node*prevNode=NULL; typename LinkedList::Node*currentNode=m_头; typename LinkedList::Node*newNode=newlinkedlist::Nodeval; int currentIndex=0; 而currentIndexget_next; currentIndex++; } prevNode->set_nextNode; m_size++; } 布拉格端区 下面是我的catch2测试:

包括 包括 包括 使用名称空间数据结构; 模板测试案例链接列表,[链接列表][模板],int{ 可以毫无问题地构造截面{ LinkedList=LinkedList; REQUIRElist.size==0; } 节可以附加值{ LinkedList=LinkedList; 附表1; REQUIRElist.size==1; REQUIRElist.get0==1; 表3.2; REQUIRElist.size==2; REQUIRElist.get1==2; } 节可以删除值{ LinkedList=LinkedList; 对于int i=0;i<5;i++ { 附表一; } REQUIRElist.size==5; REQUIRElist.get4==4; 清单4; REQUIRElist.size==4; list.remove0; REQUIRElist.size==3; REQUIRElist.get0==1; } 可以设置任意值{ LinkedList=LinkedList; 对于int i=0;i<5;i++ { 附表一; } REQUIRElist.size==5; REQUIRElist.get4==4; list.set0,9; REQUIRElist.size==5; REQUIRElist.get0==9; 列表4,22; REQUIRElist.size==5; REQUIRElist.get4==22; } 分区可以获得任意值{ LinkedList=LinkedList; 对于int i=0;i<5;i++ { 附表一; } REQUIRElist.get0==0; REQUIRElist.get1==1; REQUIRElist.get2==2; REQUIRElist.get3==3; REQUIRElist.get4==4; } Section可以在任意索引处插入值{ LinkedList=LinkedList; 对于int i=0;i<5;i++ { 附表一; } REQUIRElist.size==5; REQUIRElist.get4==4; list.insert3,99; REQUIRElist.size==6; REQUIRElist.get3==99;; REQUIRElist.get4==3; } Section精确跟踪列表的大小{ LinkedList=LinkedList; 对于int i=0;i<5;i++ { REQUIRElist.size==i; 附表一; } } Section可以判断列表何时为空{ LinkedList=LinkedList; REQUIRElist.u为空; 表3.0; REQUIRE_FALSElist.is_为空; } } 我获取SIGSEGV信号的测试是可以附加值的部分,但是如果我删除此测试,那么我将在下一个测试中获取信号

我知道这些信号通常来自于访问不应该访问的内存,但是我不确定具体发生在哪里

请注意,复制构造函数和赋值运算符重载尚未实现。我不认为这会导致这种情况,但如果我错了,请纠正我

任何帮助都将不胜感激

您的append函数已损坏。实际上,如果条件被打破,这只是第一个。如果附加到空列表,则需要增加m_size并返回

下面的代码至少在追加调用时不会崩溃

如果不执行返回,则最终会分配额外的节点,并且无法正确链接

另一方面,这段代码很奇怪

template <typename T>
LinkedList<T>::Node::~Node(){
  //Do nothing. Deletion of member m_next is out of this classes scope.
}
您正在编写一个分配内存的链表类,但是删除内存太复杂了


另外,不要使用NULL,请使用nullptr。

您的remove函数说它返回一个t,但从来不会返回。那是乌布,接得好。我更改了它并更新了我的问题。不幸的是,它没有停止信号。这解决了它!使用NULL和nullptr有什么区别?另外,我在析构函数中添加该位的原因是,通常对于具有动态分配内存的类,我知道您希望在删除该内存时释放该内存。但对于删除节点时的节点,我不一定要删除它指向的下一个节点。此组织是否存在错误做法?NULL为0。这不是一个真正的无效地址。nullptr是一种类型安全的
这意味着。是的,如果你不删除节点,你会泄漏内存。一个简单的经验法则是,每次追加一个新的,每次删除一个删除。
template <typename T>
LinkedList<T>::Node::~Node(){
  //Do nothing. Deletion of member m_next is out of this classes scope.
}