Почему я получаю «сигнал SIGSEGV, ошибка сегментации», когда пытаюсь удалить последние элементы из двусвязного списка?

#c #function #parameters #reference

Вопрос:

Это задание по программированию из университета. Основную программу мне дал профессор. Я должен создать список.h. При отладке я получаю эту ошибку сегментации. У меня также есть это:

 get (dl=..., val=lt;error reading variablegt;) at dlist.h:37  
 #include lt;iostreamgt; #include lt;exceptiongt;     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 amp; dl){ //Iinitializes dl as empty list   dl.first = nullptr;  dl.last = nullptr; }  void put(DListamp; dl, int val){ //insert a new element with value val at the beginning of the list.   DListElem* front_elem = new DListElem;  front_elem -gt;info = val;  front_elem -gt; prev = nullptr;  front_elem -gt; next = dl.first;  dl.first = front_elem;    if(dl.last==NULL) dl.last=dl.first; }  bool get(DListamp; dl, intamp; 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 -gt; info;  DListElem* buffer = new DListElem;  buffer = dl.last;  dl.last = nullptr;  dl.first = nullptr;   delete (buffer);  }  else{  val = dl.last -gt; info;  DListElem* buffer = new DListElem;  buffer = dl.last;  dl.last = dl.last -gt; prev;  dl.last -gt; next = nullptr; //this part seems to still be the problem  delete (buffer);    };  return true; }  

И это моя основная программа:

 #include lt;iostreamgt;  #include "dlist.h"  using namespace std;   int main (int argc, char *argv[]) {  DList queue; initializeDList (queue);  

вставляет 5 значений

 for (int i = 1; i lt;= 5; i  ) {  cout lt;lt; "put: " lt;lt; 10 * i lt;lt; endl;   put (queue, 10 * i);  }   

удаляет 3 значения и выводит их на консоль

 for (int j = 1; j lt;= 3; j  ){  int value;   if (get (queue, value))  cout lt;lt; " get: " lt;lt; value lt;lt; endl; }  

Я думаю, что это необходимо:

 cin.sync ();  cin.get ();  return 0;  }  

Комментарии:

1. Либо используйте malloc free (если вы в C), либо new delete . Не смешивайте и то, и другое.

2. В get() , при удалении последнего (единственного) элемента, который вы делаете dl.last = NULL; — кажется, вам тоже нужно это сделать dl.first = NULL; .

3. #ifndef _DLIST_H_ — Ваш учитель должен знать, что идентификаторы, начинающиеся с подчеркивания, зарезервированы для компилятора. Таким образом, приведенный код плохо сформирован, даже если он может работать. Есть и другие проблемы, такие как использование NULL вместо nullptr .

4. Я изменил код в соответствии с вашими рекомендациями, но он по-прежнему не работает.

5. @tokyo Рекомендации по работе вашего кода будут помещены в раздел ответов, а не в раздел комментариев. Раздел комментариев предназначен для комментариев к вашему коду.

Ответ №1:

хорошо, проблема была с функцией put(); я реализовал ее недостаточно хорошо, и она создала только один связанный список; следовательно, dl.last стал нулевым в функции get (), а выражение dl.last -gt; next = nullptr; было причиной проблемы;

это исправленный put()

 put (DList amp; dl, int val)  { //insert a new element with value val at the beginning of the list.   DListElem *front_elem = new DListElem;  front_elem-gt;info = val;  front_elem-gt;prev = nullptr;  front_elem-gt;next = dl.first;  if (dl.first != nullptr amp;amp; dl.first-gt;next == nullptr)  dl.last = dl.first;  if (dl.first != nullptr)  dl.first-gt;prev = front_elem;  dl.first = front_elem;   }