当我尝试从双向链表中删除最后一个元素时,为啥会收到“信号 SIGSEGV,分段错误”?
Posted
技术标签:
【中文标题】当我尝试从双向链表中删除最后一个元素时,为啥会收到“信号 SIGSEGV,分段错误”?【英文标题】:Why do I receive a "signal SIGSEGV, segmentation fault" when I try to delete last elements from doubly linked list?当我尝试从双向链表中删除最后一个元素时,为什么会收到“信号 SIGSEGV,分段错误”? 【发布时间】:2021-12-18 18:22:49 【问题描述】:这是大学的编程作业。主程序是教授给我的。我必须创建 dlist.h。调试时,我收到此分段错误。我也有这个:
get (dl=..., val=<error reading variable>) at dlist.h:37
#include <iostream>
#include <exception>
struct DListElem //element of the list
int info;
DListElem * prev;
DListElem * next;
;
struct DList //just stores pointers to first and last elements of the list
DListElem * first;
DListElem * last;
;
void initializeDList(DList & dl) //Iinitializes dl as empty list
dl.first = nullptr;
dl.last = nullptr;
void put(DList& dl, int val) //insert a new element with value val at the beginning of the list.
DListElem* front_elem = new DListElem;
front_elem ->info = val;
front_elem -> prev = nullptr;
front_elem -> next = dl.first;
dl.first = front_elem;
if(dl.last==NULL) dl.last=dl.first;
bool get(DList& dl, int& val)
/*Removes an item (if possible) from the end of the list. The value of the last
element is returned by the val parameter, the memory for the list element
is released. The return value indicates whether an item could be retrieved,
i.e. it returns false for an empty list and true otherwise.*/
if(dl.last==nullptr) return false;
if (dl.first==dl.last) //if there is only 1 element
val = dl.last -> info;
DListElem* buffer = new DListElem;
buffer = dl.last;
dl.last = nullptr;
dl.first = nullptr;
delete (buffer);
else
val = dl.last -> info;
DListElem* buffer = new DListElem;
buffer = dl.last;
dl.last = dl.last -> prev;
dl.last -> next = nullptr; //this part seems to still be the problem
delete (buffer);
;
return true;
这是我的主程序:
#include <iostream>
#include "dlist.h"
using namespace std;
int main (int argc, char *argv[])
DList queue;
initializeDList (queue);
插入 5 个值
for (int i = 1; i <= 5; i++)
cout << "put: " << 10 * i << endl;
put (queue, 10 * i);
删除 3 个值并将它们打印到控制台
for (int j = 1; j <= 3; j++)
int value;
if (get (queue, value))
cout << " get: " << value << endl;
我想这些是必要的:
cin.sync ();
cin.get ();
return 0;
【问题讨论】:
使用malloc
+free
(如果你在C中)或new
+delete
。不要混合两者。
在get()
中,当删除最后一个(唯一的)元素时,您会执行dl.last = NULL;
- 似乎您还需要执行dl.first = NULL;
。
#ifndef _DLIST_H_
-- 你的老师应该知道以下划线开头的标识符是为编译器保留的。因此,显示的代码格式不正确,即使它可能有效。还有其他问题,例如使用NULL
而不是nullptr
。
我根据你的建议修改了代码,但还是不行。
@tokyo 建议您的代码工作将放在答案部分,而不是评论部分。评论部分是对你的代码进行评论。
【参考方案1】:
好的,问题在于函数 put();我没有很好地实现它,它只生成了一个链表;因此, dl.last 在函数 get() 和表达式 dl.last -> next = nullptr; 中变为空。是问题的原因;
这是正确的 put()
put (DList & dl, int val)
//insert a new element with value val at the beginning of the list.
DListElem *front_elem = new DListElem;
front_elem->info = val;
front_elem->prev = nullptr;
front_elem->next = dl.first;
if (dl.first != nullptr && dl.first->next == nullptr)
dl.last = dl.first;
if (dl.first != nullptr)
dl.first->prev = front_elem;
dl.first = front_elem;
【讨论】:
以上是关于当我尝试从双向链表中删除最后一个元素时,为啥会收到“信号 SIGSEGV,分段错误”?的主要内容,如果未能解决你的问题,请参考以下文章