У меня есть простой циклически связанный список, который я составил для демонстрационных целей (я знаю, что мне следует использовать интеллектуальные указатели, но это педагогическое упражнение для памяти и структур данных). .
Частью процесса также является демонстрация рекурсии, поэтому все функции пишутся рекурсивно.
У меня были проблемы, когда это пришел к освобождению памяти из циклически связанного списка.
Неработающий код
Код: Выделить всё
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;
}
Код: Выделить всё
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);
}
}
Код: Выделить всё
#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;
};
Код: Выделить всё
#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]
Мобильная версия