I keep getting a segmentation fault error. The error seems to be caused by both remove() and size() functions:
.hpp
#ifndef linked_list_hpp
#define linked_list_hpp
#include <stdio.h>
class linked_list {
private:
class Node {
public:
double data;
Node *next;
Node *prev;
Node(double data);
};
Node *head;
Node *tail;
//--------------------------------------------------------------------------------------
public:
//--------------------------------------------------------------------------------------
size_t size() const;
//--------------------------------------------------------------------------------------
linked_list();
//--------------------------------------------------------------------------------------
double back() const;
//--------------------------------------------------------------------------------------
double at(double index) const;
//--------------------------------------------------------------------------------------
void push_back(double value);
// --------------------------------------------------------------------------------------
bool is_empty() const;
// --------------------------------------------------------------------------------------
void print() const;
//--------------------------------------------------------------------------------------
void remove(double pos);
};
#endif /* linked_list_h */
.cpp
#include "linked_list.h"
#include <iostream>
#include <stdexcept>
#include <algorithm>
//#include <boost/algorithm/string.hpp>
linked_list::linked_list(){
head = nullptr;
tail = nullptr;
}
//--------------------------------------------------------------------------------------
linked_list::Node::Node(double data){
this->data = data;
this->next = nullptr;
this->prev = nullptr;
}
//--------------------------------------------------------------------------------------
bool linked_list::is_empty() const{
return (head == nullptr && tail == nullptr);
}
//--------------------------------------------------------------------------------------
double linked_list::back() const {
if (head == nullptr) {
throw std::out_of_range("Empty list");
std::terminate();
}
return tail->data;
}
//--------------------------------------------------------------------------------------
double linked_list::at(double index) const{
if (index < 0 || index >= size()) {
throw std::out_of_range("Index out of range");
}
int i = 0;
Node* curr = head;
while(curr != nullptr && i != index){
curr = curr->next;
i++;
}
return curr->data;
}
//--------------------------------------------------------------------------------------
void linked_list::remove(double pos) {
if (pos < 0 || pos >= size()) {
throw std::out_of_range("Index out of range");
}
if (pos == 0) {
Node* temp = head;
head = head->next;
if (head != nullptr) {
head->prev = nullptr;
}
delete temp;
return;
}
Node* curr = head;
for (int i = 0; i < pos; i++) {
curr = curr->next;
}
curr->prev->next = curr->next;
if (curr->next != nullptr) {
curr->next->prev = curr->prev;
}
delete curr;
}
//--------------------------------------------------------------------------------------
void linked_list::push_back(double value){
Node* new_node = new Node(value);
if(is_empty()){
new_node->next = NULL;
new_node->prev = NULL;
head = new_node;
tail = new_node;
return;
}
else{
Node* temp = head;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = new_node;
new_node->prev = temp;
new_node->next = NULL;
tail = new_node;
}
}
//--------------------------------------------------------------------------------------
size_t linked_list::size() const {
size_t elements = 0;
Node* temp = head;
while (temp != nullptr) {
elements++;
temp = temp->next;
}
return elements;
}
//--------------------------------------------------------------------------------------
void linked_list::print() const{
Node *temp = head;
while (temp != nullptr) {
std::cout << temp->data << " ";
temp = temp->next;
}
std::cout << std::endl;
}
main.cpp
#include <iostream>
#include "linked_list.h"
#include <cstdlib>
#include <ctime>
#include <chrono>
int main() {
linked_list ls1;
linked_list ls2;
auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
srand(seed);
ls1.push_back(0);
for (int i = 1; i < 50; i++) {
int last_num = ls1.back();
int next_num = rand() % 5 + last_num + 1;
ls1.push_back(next_num);
}
double list1_at_index25 = ls1.at(25);
ls1.remove(list1_at_index25);
return 0;
}
When I debug I see that the pos passed in to remove() is not the same pos I passed in in the main function.
can anyone help me with this?
There are these issues:
You pass a node's value to remove
, while that function expects a position. If the purpose is to delete a node by its position, your main code should just call it like ls1.remove(25)
.
A parameter that is supposed to be an index/position should not be declared as double
, but as size_t
. This applies to both remove
and at
.
In remove
the tail
is never updated, yet when the removed node happens to be the tail, then tail
should be updated. Without that you may get segmentation errors when dereferencing tail
. So adapt in two places:
if (head != nullptr) {
head->prev = nullptr;
} else {
tail = nullptr;
}
and
if (curr->next != nullptr) {
curr->next->prev = curr->prev;
} else {
tail = tail->prev;
}
(There's room for avoiding this repetition of code)
There's a mix of nullptr
and NULL
. It should be nullptr