Круговой связанный список, порядок удаления деструктора, вызывающий ошибку сегментаC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Круговой связанный список, порядок удаления деструктора, вызывающий ошибку сегмента

Сообщение Anonymous »

Обзор
У меня есть простой циклически связанный список, который я составил для демонстрационных целей (я знаю, что мне следует использовать интеллектуальные указатели, но это педагогическое упражнение для памяти и структур данных). .
Частью процесса также является демонстрация рекурсии, поэтому все функции пишутся рекурсивно.
У меня были проблемы, когда это пришел к освобождению памяти из циклически связанного списка.
Неработающий код

Код: Выделить всё

void CLL::clear() {
if (!rear) { return; }

clear(rear->next);
rear = nullptr;
}

void CLL::clear(Node*& curr) {
if (curr != rear) {
clear(curr->next);
}

delete curr;
curr = nullptr;
}
Замена кода (исправляет неработающий код; неясно, почему)

Код: Выделить всё

void CLL::clear() {
if (!rear) { return; }

clear(rear);
}

void CLL::clear(Node*& curr) {
if (curr->next != rear) { // continue recursion if we're not at the end
clear(curr->next);
}

delete curr;
curr = nullptr;
}
Контекст GDB

Код: Выделить всё

Breakpoint 1, CLL::clear (this=0x7fffffffdce8, curr=@0x55555556b6e8: 0x55555556b2b0) at CLL.cpp:36
36      if (curr != rear) {
(gdb) n
37          clear(curr->next);
(gdb)
Breakpoint 1, CLL::clear (this=0x7fffffffdce8, curr=@0x55555556b2b8: 0x55555556b6e0) at CLL.cpp:36
36      if (curr != rear) {
(gdb)
40      delete curr;
(gdb)
41      curr = nullptr;
(gdb)
42  }
(gdb)
CLL::clear (this=0x7fffffffdce8, curr=@0x55555556b6e8: 0x8954fb37e656c2a4) at CLL.cpp:40
40      delete curr;
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78a53fe in __GI___libc_free (mem=0x8954fb37e656c2a4) at ./malloc/malloc.c:3368
3368    ./malloc/malloc.c: No such file or directory.
(gdb)
Остальная часть кода (для контекста)
CLL.cpp

Код: Выделить всё

#include "CLL.h"
#include 

using std::cout, std::endl;

// [DE]CONSTRUCTORS
CLL::~CLL() {
clear();
}

// HELPER FUNCTIONS
void CLL::clear() {
if (!rear) { return; }

clear(rear->next);
rear = nullptr;
}

void CLL::clear(Node*& curr) {
if (curr != rear) {
clear(curr->next);
}

delete curr;
curr = nullptr;
}

void CLL::insert(int _data, size_t index) {
if (!rear) {
rear = new Node(_data);
rear->next = rear;
}
else {
insert(_data, index, rear->next);
}
}

void CLL::insert(int _data, size_t index, Node*& curr) {
// base case 1: insert after rear (this becomes the new rear)
if ((index == 1) and (curr == rear))
{
rear->next = new Node(_data, rear->next);
rear = rear->next;
}
// base case 2: insert before the rear
else if (index == 0) {
curr = new Node(_data, curr);
}

// recursive case
else {
insert(_data, index-1, curr->next);
}
}

void CLL::display() const {
display(rear->next);
cout next);
}

size_t CLL::size(const Node* const & curr) const {
if (curr == rear) {
return 1;
}
else {
return 1 + size(curr->next);
}
}
CLL.h

Код: Выделить всё

#pragma once

#include  //size_t

class CLL {
private:
struct Node {
int data;
Node* next;

Node(): data(0), next(nullptr) {}
Node(int _data): data(_data), next(nullptr) {}
Node(int _data, Node* _next):
data(_data), next(_next) {}
};

// HELPER FUNCTIONS
void clear();

// RECURSIVE FUNCTIONS
void clear(Node*&);
void insert(int, size_t, Node*&);
void display(const Node* const &) const;
size_t size(const Node* const &) const;

Node* rear;
public:
CLL(): rear(nullptr) {}
CLL(const CLL &) = delete;  // don't copy (for now)
~CLL();

void insert(int, size_t);
void display() const;
size_t size() const;
};
main.cpp

Код: Выделить всё

#include "CLL.h"
#include 
#include  // rand(), srand(..)
#include  // time(..)

using std::cout, std::cerr, std::endl;

int main() {
CLL list;

srand(time(NULL));

// insert randomly in list
for (int n: {1,2}) {
size_t insert_index = rand() % (list.size() + 1);
// output info
cerr 

Подробнее здесь: [url]https://stackoverflow.com/questions/78723558/circular-linked-list-destructor-delete-order-causing-seg-fault[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»