C++ Stack using a doubly linked list - c++

I'm trying to implement a stack using a doubly linked list. I know that the functions for my stack class (push, pop) should contain calls to member functions of my doubly linked list class, but I'm having trouble actually implementing that.
dlist.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "dlist.hpp"
using namespace std;
void dlist::appendNodeFront(int shares, float pps){
Node *n = new Node(shares, pps);
if(front == NULL){
front = n;
back = n;
}
else {
front->prev = n;
n->next = front;
front = n;
}
}
void dlist::appendNodeBack(int shares, float pps){
Node *n = new Node(shares, pps);
if(back == NULL){
front = n;
back = n;
}
else {
back->next = n;
n->prev = back;
back = n;
}
}
void dlist::display(){
Node *temp = front;
cout << "List contents: ";
while(temp != NULL){
cout << temp->value << " ";
temp = temp->next;
}
cout << endl;
}
void dlist::display_reverse(){
Node *temp = back;
cout << "List contents in reverse: ";
while(temp != NULL){
cout << temp->value << " ";
temp = temp->prev;
}
cout << endl;
}
void dlist::destroyList(){
Node *T = back;
while(T != NULL){
Node *T2 = T;
T = T->prev;
delete T2;
}
front = NULL;
back = NULL;
}
stack.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "stack.hpp"
using namespace std;
stack::stack(){
int i;
for(i = 0; i < 1500; i++){
shares[i] = 0;
pps[i] = 0;
}
first = 0;
}
void stack::push(int num, float price){
if(first ==(1500-1)){
cout << "Stack is full" << endl;
return;
}
first++;
shares[first] = num;
pps[first] = price;
return;
}
void stack::pop(int *num, float *price){
if(first == -1){
cout << "Stack is empty" << endl;
return;
}
num = &shares[first];
price = &pps[first];
cout << shares[first] << endl;
cout << pps[first] << endl;
shares[first] = 0;
pps[first] = 0;
first--;
return;
}
Should the push function in stack basically be a call to appendNodeFront() or appendNodeback()? Any help or advice is greatly appreciated!

You can create a stack class, then use linked list class as its container. In a linked list class there is virtually no limit to the number of items, so you add artificial limit to make it work like a stack. In a linked list, items can be added/removed anywhere in the list, you can limit add/remove the tail node only to make it work like stack. The example below demonstrate the usage.
Node that this is purely a programming exercise. Stack is relatively primitive compared to Doubly-linked list. Encapsulating a linked-list inside stack has no advantage. Also note, I declared all members as public for the sake of simplifying the problem, you may want to change some members to protected/private
#include <iostream>
#include <fstream>
#include <string>
using std::cout;
class Node
{
public:
Node *prev;
Node *next;
int shares;
float pps;
Node(int vshares, float vpps)
{
shares = vshares;
pps = vpps;
prev = next = nullptr;
}
};
class dlist
{
public:
Node *head;
Node *tail;
dlist()
{
head = tail = nullptr;
}
~dlist()
{
destroy();
}
void push_back(int shares, float pps)
{
Node *node = new Node(shares, pps);
if (head == NULL)
{
head = tail = node;
}
else
{
tail->next = node;
node->prev = tail;
tail = node;
}
}
void destroy()
{
Node *walk = head;
while (walk)
{
Node *node = walk;
walk = walk->next;
delete node;
}
head = tail = nullptr;
}
};
class stack
{
public:
int maxsize;
int count;
dlist list;
stack(int size)
{
count = 0;
maxsize = size;
}
void push(int num, float price)
{
if (count < maxsize)
{
list.push_back(num, price);
count++;
}
}
void pop()
{
Node *tail = list.tail;
if (!tail)
{
//already empty
return;
}
if (tail == list.head)
{
//only one element in the list
delete tail;
list.head = list.tail = nullptr;
count--;
}
else
{
Node *temp = list.tail->prev;
delete list.tail;
list.tail = temp;
list.tail->next = nullptr;
count--;
}
}
void display()
{
Node *walk = list.head;
while (walk)
{
cout << "(" << walk->shares << "," << walk->pps << ") ";
walk = walk->next;
}
cout << "\n";
}
};
int main()
{
stack s(3);
s.push(101, 0.25f);
s.push(102, 0.25f);
s.push(103, 0.25f);
s.push(104, 0.25f);
s.display();
s.pop();
s.display();
return 0;
}

Related

Trying to initialize a linked list using array

I need to define a class of linked list,List, in a way such that object of class can be defined in two ways,
List obj1 = L1();//head=0
List obj2 = L2(given_arr[], size of array) // I would be given an array, whose elements are elements of list
so, I need to form a construter for both,
for obj1, Its easy.
List(){head=0};
But I am not abe to do so for second type of object.
I tried to form a program for this.
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head;
int arr[];
List() { head = 0; }
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
int i;
head->val = arr[0];
for (i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[4] = {9, 89, 0, 43};
List* M = new List();
List* L = new List(barr[4], 4);
L->display();
return 0;
}
This program doesn't work. Please suggest a way to do so.
Make these changes to your main().
int main() {
int barr[] = {9, 89, 0, 43}; // No need to specify size if you're initializing
// List* M = new List(); // unused
// Your array is barr, barr[4] makes no sense. You also don't allocate the List,
// the list allocates
List L = List(barr, sizeof(barr) / sizeof(barr[0]);
L.display(); // -> to .
return 0;
}
This now compiles, but immediately segfaults. Simply running the program in the debugger shows a simple error. The line head->val = arr[0]; attempts to dereference a null pointer. Which takes us to the next thing. Use nullptr, not NULL or 0.
Your array constructor was over-complicated, you just need this:
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
Your addnode() function already handled an empty list. Fixing that, your code should run. I made a couple other small changes, mostly trimming cruft out. Here's your complete code:
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head = nullptr;
List() = default;
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[] = {9, 89, 0, 43};
List L = List(barr, sizeof(barr) / sizeof(barr[0]));
L.display();
return 0;
}

finding min, max, and average of linked list

I have a program in which I'm supposed to build functions using linked lists to perform a variety of tasks. Currently, I am having an issue finding the min and max value of the linked list. For some reason when both come out to be the highest which digit which is 9, and when I try to find the average of the list, it still comes out as 9.
additionally, I think it's interfering with my pop function which is supposed to delete the last item, but when I try to work it by sections one part wont work until he previous section is running for whatever reason.
here is my header
#include <iostream>
using std::cout;
using std::endl;
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
class LinkedList
{
private:
struct Node
{
int data;
Node *next;
};
int size;
Node *head, *tail;
public:
LinkedList();
~LinkedList();
// misc
void display();
// sorting and searching
// reverse --> sorting in descending
int linearSearch(int key);
void sort();
void reverse();
// various math
int min();
int max();
int mean();
// adding
void append(int num);
void insert(int num, int pos);
// removing
void pop();
void remove(int pos);
};
#endif // LINKEDLIST_H
the header's source file
#include "linkedlist.h"
LinkedList::LinkedList()
{
head = nullptr;
tail = nullptr;
size = 0;
}
LinkedList::~LinkedList()
{
if(head != nullptr)
{
Node *temp;
while(head != nullptr)
{
temp = head->next;
// deletes head
delete head;
// goes to next element
head = temp;
}
}
}
void LinkedList::display()
{
Node *temp = head;
for(int i = 0; i < size; i++)
{
cout << temp->data << "\t";
temp = temp->next;
}
cout << endl;
}
void LinkedList::append(int num)
{
// list is empty
if(head == nullptr)
{
head = new Node;
head->data = num;
head->next = nullptr;
// sets tail to head
tail = head;
}
else
{
// creates new node
Node *temp = new Node;
// sets new node data
temp->data = num;
temp->next = nullptr;
// sets previous tail link to new node
tail->next = temp;
// sets this node to new tail
tail = temp;
}
// increments size
size++;
}
void LinkedList::pop()
{
if(size > 1)
{
Node *temp = head;
// loops to node before tail
while(temp->next->next != nullptr)
{
temp = temp->next;
}
// deletes tail
delete tail;
// sets new tail
tail = temp;
tail->next = nullptr;
}
// if there's only one item
else if(size == 1)
{
Node *temp = tail;
// head and tail are now null
head = nullptr;
tail = nullptr;
// deletes node
delete temp;
}
size--;
}
void LinkedList::insert(int num, int pos)
{
if(pos ==0)
{
Node *temp=new Node;
temp->data=num;
temp->next=head;
head=temp;
}
if(pos>1)
{
Node *pre=new Node;
Node *cur=new Node;
Node *temp=new Node;
cur=head;
for(int i=1;i<pos+1;i++)
{
pre=cur;
cur=cur->next;
}
temp->data=num;
pre->next=temp;
temp->next=cur;
}
size++;
}
int LinkedList::linearSearch(int key)
{
Node *temp = head;
for(int i = 0; i < size; i++)
{
if(temp->data == key)
{
return i;
}
temp = temp->next;
}
return -1;
}
int LinkedList::max()
{
int max = INT_MIN;
for(int i = 0; i < size; i++)
{
while (head != NULL)
{
if (head->data < max)
max = head->data;
head = head->next;
}
}
}
int LinkedList::min()
{
int min = INT_MAX;
for(int i = 0; i < size; i++)
{
while (head != NULL)
{
if (head->data < min)
min = head->data;
head = head->next;
}
}
}
void LinkedList::reverse()
{
Node* temp = head;
// Traverse the List
while (temp) {
Node* min = temp;
Node* r = temp->next;
// Traverse the unsorted sublist
while (r)
{
if (min->data < r->data)
min = r;
r = r->next;
}
// Swap Data
int x = temp->data;
temp->data = min->data;
min->data = x;
temp = temp->next;
}
}
void LinkedList::remove(int pos)
{
Node *temp = head;
if(pos ==0)
{
head = temp->next;
free(temp);
}
if(pos>1)
{
for(int i=0; temp!=NULL && i<pos-1;i++)
{
temp=temp->next;
}
temp->next = temp->next->next;
free(temp->next);
temp->next = temp->next;
}
size--;
}
int LinkedList::mean()
{
int sum = 0;
float avg = 0.0;
Node *temp = head;
while (head != NULL)
{
sum += temp->data;
temp = temp->next;
}
// calculate average
avg = (double)sum / size;
}
void LinkedList::sort()
{
Node* temp = head;
// Traverse the List
while (temp) {
Node* min = temp;
Node* r = temp->next;
// Traverse the unsorted sublist
while (r) {
if (min->data > r->data)
min = r;
r = r->next;
}
// Swap Data
int x = temp->data;
temp->data = min->data;
min->data = x;
temp = temp->next;
}
}
And the main
#include <iostream>
#include "linkedlist.h"
using namespace std;
int main()
{
LinkedList nums;
// adding through append
nums.append(8);
nums.append(6);
nums.append(7);
nums.append(8);
nums.append(0);
nums.append(9);
// displays list
cout << "List after append: " << endl;
nums.display();
cout << endl;
// adding through insert
nums.insert(1, 0);
nums.insert(5, 4);
nums.insert(3, 8);
// displays list
cout << "List after inserting: " << endl;
nums.display();
cout << endl;
// testing searching
cout << "Testing linear search:" << endl;
int pres = nums.linearSearch(7);
if(pres < 0)
{
cout << "7 is not present in the list." << endl;
}
else
{
cout << "7 can be found at location " << pres << endl;
}
pres = nums.linearSearch(5);
if(pres < 0)
{
cout << "5 is not present in the list." << endl;
}
else
{
cout << "5 can be found at location " << pres << endl;
}
cout << endl;
// does math
cout << "Minimum, maximum, and average before removing any items: " << endl;
cout << "Min: " << nums.min() << endl;
cout << "Max: " << nums.max() << endl;
cout << "Mean: " << nums.mean() << endl << endl;
// displays items reversed
cout << "Items reversed: " << endl;
nums.reverse();
nums.display();
cout << endl;
// removing through pop
nums.pop();
nums.pop();
// displays list
cout << "List after popping: " << endl;
nums.display();
cout << endl;
// removing through remove
nums.remove(0);
nums.remove(2);
nums.remove(4);
// displays list
cout << "List after removing: " << endl;
nums.display();
cout << endl;
// displays items sorted
cout << "Items sorted: " << endl;
nums.sort();
nums.display();
cout << endl;
// does math
cout << "Minimum, maximum, and average after removing items: " << endl;
cout << "Min: " << nums.min() << endl;
cout << "Max: " << nums.max() << endl;
cout << "Mean: " << nums.mean() << endl << endl;
// testing searching
cout << "Testing linear search:" << endl;
pres = nums.linearSearch(7);
if(pres < 0)
{
cout << "7 is not present in the list." << endl;
}
else
{
cout << "7 can be found at location " << pres << endl;
}
pres = nums.linearSearch(5);
if(pres < 0)
{
cout << "5 is not present in the list." << endl;
}
else
{
cout << "5 can be found at location " << pres << endl;
}
return 0;
}
the only parts I'm really struggling with is the max, min, and mean along with getting my pop function to actually initiate. I know that the pop function is written correctly but ever since I made the max and min it wont work now.
There are several bugs that I have found in the code, and I have several remarks about it:
You should use spaces, and more consistently. There are places without enough spacing, and places with too many blank lines!
If you have two functions such as insert and append or pop and remove, they should use each other, meaning, append is just insert(0) (notice how I changed it in the code).
You are using double loops where it doesn't make sense (it isn't an error, but it is a bug!).
In the function max, you were doing the wrong comparison, asking if max is bigger than the current value...
You never return a value from min and max, which should at least create a warning in the compilation process!
You were creating empty nodes, and then you just put different values in their pointers, meaning that this new memory was still allocated (since there was no delete), but there was no way to access these anymore (this is a memory leak).
The biggest bug of all - When you loop in the min and max functions, you change the head of the list, which is a major bug (and that is why you got bugs after using this function). The solution is a simple but important lesson in C++ - Const Correctness.
What is const correctness, and why is it important?
When you have a function, that does not change the state of your object, it should be declared const. This is our way to tell the compiler (and other programmers) that it mustn't change the state of our object. For example, min, max and average are classic const functions - they simply make a calculation that does not change the list, and return. If you had written const in the declaration of those, the compilation would have failed, since you actually changed the list (changing the head), although you shouldn't!
Moreover, when receiving objects into a function, whenever possible, you should make the const T& where T is a type. They will enforce that you are using only const functions of this type.
Also, I suggest compiling (at least on g++) with the flags -Wpedantic -Werror'. The first adds some warnings about ISO C++ standards and the second makes all warnings into errors (and thus, yourmin,maxandmean` should not compile, since they don't return a value).
Here is the code:
class LinkedList
{
private:
struct Node
{
int data;
Node *next;
Node(int data_, Node* next_ = nullptr) :
data(data_),
next(next_)
{
}
};
int size;
Node *head, *tail;
public:
LinkedList();
~LinkedList();
void clear();
// various math
int min() const;
int max() const;
int average() const;
// adding
void append(int data);
void insert(int data, int pos);
// removing
void pop();
void remove(int pos);
};
LinkedList::LinkedList()
{
head = nullptr;
tail = nullptr;
size = 0;
}
LinkedList::~LinkedList()
{
clear();
}
void LinkedList::clear()
{
if (head != nullptr)
{
Node *temp;
while(head != nullptr)
{
temp = head->next;
delete head;
head = temp;
}
}
head = nullptr;
tail = nullptr;
size = 0;
}
void LinkedList::display()
{
Node *temp = head;
for(int i = 0; i < size; i++)
{
std::cout << temp->data << "\t";
temp = temp->next;
}
std::cout << std::endl;
}
void LinkedList::insert(int data, int pos)
{
if (pos == 0)
{
Node* prev_head = head;
head = new Node(data, prev_head);
if (size == 0)
{
tail = head;
}
}
else
{
Node *pre=nullptr;
Node *cur = head;
for(int i = 0 ; i < pos + 1; ++i)
{
pre = cur;
cur = cur->next;
}
Node *temp = new Node(data, cur);
pre->next = temp;
}
++size;
}
void LinkedList::append(int data)
{
insert(data, 0);
}
void LinkedList::pop()
{
if (size == 1)
{
Node *temp = tail;
head = nullptr;
tail = nullptr;
delete temp;
}
else
{
Node *temp = head;
while(temp->next != tail)
{
temp = temp->next;
}
Node* node_to_pop = tail;
tail = temp;
tail->next = nullptr;
delete node_to_pop;
}
--size;
}
int LinkedList::max() const
{
int max = INT_MIN;
for (Node* temp = head; temp != nullptr; temp = temp->next)
{
if (temp->data > max)
{
max = temp->data;
}
}
return max;
}
int LinkedList::min() const
{
int min = INT_MAX;
for(Node* temp = head; temp != nullptr; temp = temp->next)
{
if (head->data < min)
{
min = temp->data;
}
}
return min;
}
int LinkedList::average() const
{
int sum = 0;
for(Node* temp = head; temp != nullptr; temp = temp->next)
{
sum += temp->data;
temp = temp->next;
}
return (double)sum / size;
}

Dot Product Calculation Link List Implementation

I am trying to implement the a dot product calculation formula into the linked list implementation on my below code and I am having the below error:
request for member 'add_node' in 'B', which is of pointer type 'linked_list {aka node*}' (maybe you meant to use '->' ?)
How can I clear that and make working code? I don't want to use classes as well
#include <iostream>
#include <stdlib.h>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
typedef node* linked_list;
node *head = NULL;
node *tail = NULL;
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
int product=0;
while(A!=0 && B!=0)
{
if(A->index == B->index)
{
product = product + A->data * B->data;
A=A->next;
B=B->next;
}
else if(A->index < B->index)
{
A=A->next;
}
else
{
B=B->next;
}
}
return product;
return 0;
}
The error tells you what you need to know. linked_list is a pointer. You need to use the -> operator, not the dot operator.
Additionally, your node struct does not contain a method called add_node(). In fact it doesn't contain any methods at all.
#include <iostream>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
node* gethead()
{
return head;
}
};
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
display(A.gethead());
display(B.gethead());
int product=0;
node *current_a = A.gethead();
node *current_b = B.gethead();
while(current_a != 0 && current_b!=0)
{
if(current_a->index == current_b->index)
{
product = product + current_a->data * current_b->data;
current_a=current_a->next;
current_b=current_b->next;
}
else if(current_a->index < current_b->index)
{
current_a=current_a->next;
}
else
{
current_b=current_b->next;
}
}
cout<<"\nDot Product : "<< product<<endl;
return 0;
}
enter code here

C++: What is best way to destruct this code? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I want to know proper way of destructing this code as I'm facing many random issues. However, this piece of code is working as I'm calling ~CacheFrame() first and than assinging nullptr to pageMap inside ~LruCache()
#include <iostream>
#include <unordered_map>
#include <list>
using namespace std;
struct Node {
int pageNumber;
Node *next;
Node *prev;
Node(int pageNumber, Node *prev, Node *next) {
this->pageNumber = pageNumber;
this->next = next;
this->prev = prev;
}
};
class CacheFrame {
const size_t maxSize;
int size;
Node *head, *tail;
public:
CacheFrame(int maxSize) : maxSize(maxSize) {
size = 0;
head = tail = nullptr;
}
~CacheFrame() {
cout << "CacheFrame Destructor called" << endl;
tail = nullptr;
while (head) {
Node *temp = head->next;
head->next = nullptr;
head->prev = nullptr;
delete head;
head = temp;
}
}
void MovePageToFront(Node* page) {
if (page == nullptr || page == head) {
return;
}
if (page == tail) {// point tail to second last element
tail = tail->prev;
tail->next = nullptr;
}
page->prev->next = page->next;
if (page->next)
page->next->prev = page->prev;
page->next = head;
head->prev = page;
head = page;
}
Node* InsertPage(int pageNumber) {
Node *page = new Node(pageNumber, nullptr, nullptr);
if (!head) {
head = tail = page;
size = 1;
return head;
}
if (size < maxSize) {
size++;
} else {
Node *temp = tail;
tail = tail->prev;
tail->next = nullptr;
delete temp;
}
page->next = head;
head->prev = page;
head = page;
return page;
}
size_t getCurrentSize() {
return size;
}
size_t getMaxSize() {
return maxSize;
}
int getLastPageNumber() {
return tail->pageNumber;
}
void printFrame() {
Node *start = head;
cout << "Frame" << endl;
while (start) {
cout << "-----" << endl;
cout << "| " << start->pageNumber << " |" << endl;
start = start->next;
}
cout << "-----"<< endl;
}
};
class LruCache {
const size_t size;
CacheFrame frame;
unordered_map<int, Node*> pageMap;
public:
LruCache(int size): size(size), frame(CacheFrame(size)) {}
~LruCache() {
cout << "LruCache Destructor called" << endl;
frame.~CacheFrame();
for (auto it: pageMap) {
cout << "Deleting " << it.first << " from map" << endl;
it.second = nullptr;
pageMap.erase(it.first);
// if (it.second) {
// it.second->next = nullptr;
// it.second->prev = nullptr;
// delete it.second;
// }
}
}
void accessPage(int pageNumber) {
cout << "Access Page : " << pageNumber << endl;
if (pageMap.find(pageNumber) != pageMap.end()) {// page hit
cout << "Page Hit" << endl;
frame.MovePageToFront(pageMap[pageNumber]);
} else {//page miss
cout << "Page Miss" << endl;
if (frame.getMaxSize() == frame.getCurrentSize()) {
pageMap.erase(frame.getLastPageNumber());
}
pageMap[pageNumber] = frame.InsertPage(pageNumber);
}
frame.printFrame();
}
};
int main() {
LruCache cache = LruCache(3);
int array[] = {4,2,1,1,4,3,7,8,3};
for (auto it: array) {
cache.accessPage(it);
}
return 0;
}
C++: What is best way to destruct this code?
You mean to free resources.
In case of unordered_map
The way to do it right is not to do it. A unordered_map will automatically release resources when it's destroyed for anything allocated automatically.
Unless you allocated the values with new, you don't delete them.
In case of linked list
~CacheFrame()
{
Node *temp = head->next, *temp2;
while(temp != NULL)
{
temp2 = temp;
temp = temp->next;
delete temp2;
}
}

Segmentation Fault (core dumped) when trying to run Queue program - C++

I keep getting a Segmentation fault (core dumped) error every time I try to run my code with g++ on Linux. It compiles fine, but then that happens ... All the functions (remove, add and print) seem to have the same problem, I can't seem to figure out what's wrong... Please heeeelppp.
#include <iostream>
#include <string>
using namespace std;
//Create a node struct
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
//set to NULL
Queue::Queue() {
head = tail = NULL;
size = 0;
}
//destructor
//call remove until empty
Queue::~Queue() {
while (!isEmpty())
remove();
}
//adds a node with the given data at the back of the queue
void Queue::add(int d) {
Node *temp = new Node();
temp->data = d;
temp->next = NULL;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
//removes the node at the head of the queue and returns its data
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *temp = new Node;
temp = head;
int value = head->data;
//moves pointer to next node
head = head->next;
cout << "Removed: " << head->data << endl;
size--;
delete temp;
return value;
}
}
//determines if the queue is empty
bool Queue::isEmpty() {
return (size == 0);
}
//prints the contents of the queue from front to back, or front
//to back, depending on the value of the parameter
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p = new Node;
if (o == true) {
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
p = head;
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
p = tail;
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(8);
return 0;
}
EDIT: I've made some changes to the code... But I'm still getting the same error. I assume I'm not updating the head and the tail and/or the next and prev nodes correctly... I don't know why it's wrong or what I'm missing, though.
#include <iostream>
#include <string>
using namespace std;
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
Queue::Queue() {
head = tail = NULL;
size = 0;
}
Queue::~Queue() {
while (!isEmpty())
remove();
}
void Queue::add(int d) {
Node *temp = new Node;
temp->data = d;
temp->next = NULL;
temp->prev = tail;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
return 0;
} else {
Node *temp = head;
int value = head->data;
cout << "Removed: " << head->data << endl;
//moves pointer to next node
head = head->next;
head->prev = NULL;
size--;
delete temp;
return value;
}
}
bool Queue::isEmpty() {
return (size == 0);
}
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p;
if (o == true) {
p = head;
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
p = tail;
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(9);
q.add(10);
q.add(11);
q.add(12);
q.add(13);
q.add(14);
q.add(15);
q.add(16);
q.remove();
q.remove();
q.printQueue(true);
q.printQueue(false);
return 0;
}
Lots of problems:
You have a double-linked Node but never update its prev member in the add/remove methods.
You are keeping track of both the Queue head/tail but don't properly update them when you add/remove nodes.
Both your forward and reverse loops in printQueue() are wrong and result in an infinite loop for any queue with 2 or more elements. Queue output should be just something like:
Node *p = head;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
Possible null pointer deference in remove() at cout << "Removed: " << head->data << endl; since you've already moved the head pointer by this time. Move the head after the cout.
Memory leak in Queue::remove() at Node *temp = new Node;. Just do Node* temp = head;.
Memory leak in Queue::printQueue() at Node *p = new Node;. You don't need to allocate a node here.
No return value in remove() for an empty queue.
Edit
Don't forget to initialize the tail when adding a node to an empty list:
if (isEmpty()) {
head = temp;
tail = temp;
}
To remove a node from the head of a non-empty list it should be something like:
Node *temp = head;
head = head->next;
if (head) head->prev = NULL;
size--;
delete temp;
if (isEmpty()) tail = NULL;