making a dynamic queue in C++ - c++

I'm trying to make a dynamic queue in C++ and I wrote most of the code, yet it doesn't work, could someone be kind enough to look through it and tell me what's wrong? :)
Also please comment on the coding style I wish to improve.
I wrote a main function to test the program and this should be the expected result:
data1=1
data1=1 data2=2
1 2 3 4 5 6
Del:1 Del:2 Del:3
This is my code:
#include <iostream>
template<typename T>
class Queue
{
struct Node
{
T data;
Node* next;
};
Node* head;
Node* tail;
int qsize;
public:
Queue()
{
head = NULL;
tail = NULL;
qsize = 0;
}
bool empty()
{
if(qsize = 0){return true;}
else {return false;}
}
void put(const T& data)
{
Node *newNode = new Node;
if(qsize)
{
tail->next = newNode;
newNode->data = data;
newNode->next = NULL;
tail = newNode;
}
else
{
head = tail = newNode;
newNode->data = data;
newNode->next = NULL;
}
qsize++;
}
T get()
{
T val;
Node *temp;
if(empty())
{
std::cout << "queue is empty" << std::endl;
}
else
{
val = head->data;
temp = head;
head = head->next;
delete temp;
qsize--;
return val;
}
}
void destroyQueue()
{
while(!empty())
{
std::cout<<"DEL:";
get();
}
}
~Queue()
{
destroyQueue();
}
};
int main()
{
int data1,data2;
Queue<int>* q = new Queue<int>();
q->put(1);
data1 = q->get();
std::cout << " data1=" << data1 << std::endl;
q->put(1);
q->put(2);
data1 = q->get();
data2 = q->get();
std::cout << " data1=" << data1
<< " data2=" << data2 << std::endl;
q->put(1);
q->put(2);
q->put(3);
q->put(4);
q->put(5);
q->put(6);
while (!q->empty()) std::cout << " " << q->get();
std::cout << std::endl;
q->put(1);
q->put(2);
q->put(3);
delete q;
}

if(qsize = 0) should be if(qsize == 0) - don't assign, compare!

Related

An implementation of Stack in C++ using doubly LL fails with an exception “EXC_BAD_ACCESS (code=2, address=0x7fff5df48ff8)”

Goal:
I've implemented a stack using a doubly linked list. I'm using a doubly linked list because the input size is 1 billion and using any other data structure will not render an optimal solution.
Problem:
I have two objects declared in the class MyStack() called root and tail. I want to initialize the values of these two objects to NULL initially. Later, when I call the push() method for the first time, it'll override the values of objects root and tail.
In my case, the code fails with an exception, “EXC_BAD_ACCESS (code=2, address=0x7fff5df48ff8) because the value of root is not NULL. I'm not sure where I should be initializing the values so that root and tail don't get overridden until push() is called.
The following is the .h file:
#ifndef UNTITLED_MYSTACK_H
#define UNTITLED_MYSTACK_H
class MyStack {
void* data;
MyStack* next;
MyStack* prev;
MyStack* root;
MyStack* tail;
public:
MyStack();
MyStack(void *data);
MyStack * newNode();
void *newNode(void* data);
bool isEmpty(MyStack *root);
void push(void *data);
void *pop();
int size();
virtual ~MyStack();
};
#endif //UNTITLED_MYSTACK_H
The following is the .cpp file
#include <iostream>
#include <climits>
#include <cstdlib>
#include "MyStack.h"
using namespace std;
MyStack::MyStack() : root(NULL), tail (NULL) {} // <-- ERROR here -->
MyStack::MyStack(void *data) : data(data) {} // <-- ERROR here -->
MyStack * MyStack::newNode()
{
MyStack* stackNode;
stackNode = new MyStack();
stackNode->data = NULL;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
void* MyStack::newNode(void* data)
{
MyStack* stackNode;
stackNode = new MyStack(data);
stackNode->data = data;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
bool MyStack::isEmpty(MyStack *root) {
return (root == NULL);
}
void MyStack::push(void *val) {
if (isEmpty(root)) {
root->data = newNode(val);
tail->data = newNode(val);
tail->next = newNode();
tail = tail->next;
root->next = tail;
tail->prev = root;
cout << " Element pushed to stack" << tail->data << endl;
}
else {
tail->data = val;
tail->next = newNode();
tail->next->prev = tail;
tail = tail->next;
cout << " Element pushed to stack" << tail->data << endl;
}
}
void *MyStack::pop() {
if (isEmpty(tail)) {
cout << "Stack is empty" << endl;
return NULL;
}
MyStack* evictedN = new MyStack();
evictedN = tail;
tail = tail->prev;
tail->next = newNode();
tail = tail->next;
return evictedN->data;
}
int MyStack::size() {
if(isEmpty(root)) {
cout << "Size is empty" << endl;
return 0;
}
int count = 1;
while (tail->prev != NULL) {
count += 1;
tail = tail->prev;
}
return count;
}
MyStack::~MyStack() {
}
//here is my main method
int main() {
MyStack s;
elem_t* elem;
elem->value = 10;
elem->other = 10 >> 1;
s.push(elem);
cout << elem->value << endl;
cout << elem->other << endl;
cout << s.pop() << endl;
cout << s.size() << endl;
return 0;
}
The main problem is that you are not distinguishing between the stack and the nodes that the stack contains. MyStack::newNode() is returning a completely new stack, not a new node. According to this code:
void MyStack::push(void *val) {
if (isEmpty(root)) {
root->data = newNode(val);
tail->data = newNode(val);
tail->next = newNode();
tail = tail->next;
root->next = tail;
tail->prev = root;
cout << " Element pushed to stack" << tail->data << endl;
}
else {
tail->data = val;
tail->next = newNode();
tail->next->prev = tail;
tail = tail->next;
cout << " Element pushed to stack" << tail->data << endl;
}
}
in the case where the root is NULL, isEmpty(root) returns true, so we go ahead and dereference it anyway by accessing root->data. This is undefined behavior.
You need to distinguish between a node and a stack and rewrite the code with that distinction in mind. elem_t could be the node type, or you could define a new class.
here is the MyStack_class.h file:
#ifndef MYSTACK_CLASS_H
#define MYSTACK_CLASS_H
class elem_t {
public:
int value;
int other;
elem_t() {};
elem_t(int value, int other) : value(value), other(other) {}
~elem_t() {};
};
class MyStack {
private:
void* data;
MyStack* next;
MyStack* prev;
public:
MyStack () {}
MyStack(void* val) : data(val), next(nullptr), prev(nullptr) {}
~MyStack() {}
MyStack* newNode();
MyStack* newNode(void*);
void push(void*);
void* pop();
int size();
};
#endif
~
The following is the MyStack_class.cpp file:
#include <iostream>
#include "MyStack_class.h"
#include <cstdlib>
using namespace std;
int count = 0;
MyStack* root = new MyStack();
MyStack* tail = new MyStack();;
MyStack* MyStack::newNode()
{
MyStack* stackNode;
stackNode = new MyStack();
stackNode->data = NULL;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
MyStack* MyStack::newNode(void* data)
{
MyStack* stackNode;
stackNode = new MyStack(data);
stackNode->data = data;
stackNode->next = NULL;
stackNode->prev = NULL;
return stackNode;
}
void MyStack::push (void* val)
{
if (count == 0) {
root = newNode(val);
tail = newNode(val);
tail->next = newNode();
tail = tail->next;
root->next = tail;
tail->prev = root;
count++;
cout << "Element: " << count << " pushed to Stack" << endl;
}
else {
tail->data = val;
tail->next = newNode();
tail->next->prev = tail;
tail = tail->next;
count++;
cout << " Element " << count << " pushed to stack" << endl;
}
}
void* MyStack::pop()
{
if (count == 0) {
cout << "Stack is empty" << endl;
exit(1);
}
MyStack* evictedN = new MyStack();
tail = tail->prev;
evictedN = tail;
tail->next = tail->next->prev = NULL;
count--;
return evictedN->data;
}
int MyStack::size() {
int cnt = 0;
while(root->next != NULL) {
cnt++;
root = root->next;
}
return cnt;
}
The MyStack_class library is used in the following program which can be called
main.cpp or anything that you'd like:
#include <iostream>
#include <cstdlib>
#include "MyStack_class.h"
#define NELEM 1000
using namespace std;
void
example() {
MyStack* s = new MyStack;
for (int i = 0; i < NELEM; i++) {
elem_t* elem = new elem_t(i , i >> 1);
if (elem == NULL) {
exit(1);
}
s->push(elem);
cout << "the pushed element's value and other respectively : " << elem->value << " " << elem->other << endl;
}
cout << "Stack size : " << s->size() << endl;
for (int i = (NELEM-1); i > 0; i--) {
elem_t* elem = static_cast<struct elem_t*>(s->pop());
if (elem->value != i) {
cout << "Error: i is " << i << "and elem-value is " << elem->value << endl;
}
cout << "The popped element's value and other respectively: " << elem->value << " " << elem->other << endl;
delete elem;
}
delete s;
}
int
main()
{
example();
return 0;
}
Here's how my Makefile looks:
MyStack_class: MyStack_class.o main.o
g++ MyStack_class.o main.o -o MyStack_class
MyStack_class.o: MyStack_class.cpp main.cpp
g++ -c -std=c++0x MyStack_class.cpp main.cpp
clean:
rm MyStack_class.o main.o MyStack_class

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;
}
}

Linked lists insertion (core dumped)

my header and implimentation file
#ifndef VIKTOR_H_
#define VIKTOR_H_
#include <iostream>
template <class DataType>
class viktor {
private:
template <class NodeType>
struct Node {
NodeType data;
Node<NodeType> * next;
};
Node<DataType> * backPtr;
int length;
public:
viktor();
~viktor();
DataType &operator [] (int) const;
void push(const DataType &);
friend std::ostream &operator << (std::ostream &strm, const
viktor<DataType> &A){
for(int i = 0; i < A.length; ++i) {
strm << A[i] << " " << std::flush;
}
strm << std::endl;
return strm;
}
};
template <class DataType>
viktor<DataType>::viktor() {
backPtr = nullptr;
length = 0;
}
template <class DataType>
viktor<DataType>::~viktor() {
if ( length == 0 ) return;
Node<DataType>* previousPtr = backPtr;
Node<DataType>* nextPtr = backPtr->next;
while( nextPtr != backPtr )
{
nextPtr = nextPtr->next;
previousPtr->next = nullptr;
delete previousPtr;
length--;
}
backPtr->next = nullptr;
delete backPtr;
}
template <class DataType>
void viktor<DataType>::push(const DataType &item) {
Node<DataType>* newNode = new Node<DataType>;
newNode->data = item;
std::cout << "data: " << newNode->data << std::endl;
if(length != 0) {
newNode->next = backPtr->next;
backPtr->next = newNode;
}
else {
newNode->next = newNode;
}
backPtr = newNode;
length += 1;
//std::cout << "Finished pushing..." << std::endl;
}
template <class DataType>
DataType &viktor<DataType>::operator [] (int i) const {
Node<DataType>* conductor = backPtr;
if (i > length) {
throw "Item is inaccessible";
}
for (int j = 0; j <= i; ++j) {
conductor = conductor->next;
}
return conductor->data;
}
#endif //VIKTOR_H_
i am having problems with this function
template <class DataType>
void viktor<DataType>::push(const DataType &item) {
Node<DataType>* newNode = new Node<DataType>;
newNode->data = item;
std::cout << "data: " << newNode->data << std::endl;
if(length != 0) {
newNode->next = backPtr->next;
backPtr->next = newNode;
}
else {
newNode->next = newNode;
}
backPtr = newNode;
length += 1;
//std::cout << "Finished pushing..." << std::endl;
}
i am using this test driver
int main() {
viktor<int> blah;
blah.push(2);
std::cout << blah << std::endl;
}
now it works if i only push once but if i do
blah.push(1);
blah.push(2);
it runs and prints all of the data that i want but at the end of the program it dumps my core (i can provide the specific error if you want but it's just a memory map and then aborted (core dumped))
i fixed it! thanks Some programmer dude! so the problem was my deconstructor, what i did was changed previousPtr->next = nullptr; to previousPtr = previousPtr->next;

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;

What are self referential C++ types good for?

What are use cases for self-referential types?
By self referential types, I mean:
class T {
T *ptr; // member variable that references the type of the class
};
It is one of the most efficient ways to build linked lists or tree
hierarchies.
#include <iostream>
class linked_ints {
public:
linked_ints() : next(nullptr), x(0) {}
linked_ints* next;
int x;
};
void print(linked_ints* b) {
if(b == nullptr) return;
do {
std::cout << b->x << std::endl;
} while((b = b->next));
}
int main()
{
linked_ints x, y, z;
x.next = &y; y.next = &z;
print(&x);
return 0;
}
One example I can think of are linked lists.
The example borrowed from here:
#include<iostream>
struct Node{
int data;
Node* next;
};
void InsertAfter(Node **head, int value){
if(*head==NULL){
Node* temp=NULL;
temp = new Node;
temp->data = value;
temp->next = NULL;
*head = temp;
}else{
Node *temp = new Node;
temp->data = value;
temp->next = (*head)->next;
(*head)->next = temp;
}
}
void DeleteAfter(Node **head){
if(*head==NULL){
return;
}else{
Node *temp = NULL;
temp = (*head)->next;
(*head)->next = (*head)->next->next;
delete temp;
temp=NULL;
}
}
int DeleteAll(Node **head,int value){
int count=0;
Node *p = NULL;
Node *q = (*head);
if(*head==NULL){
count =0;
}else{
while((q)!=NULL){
if((q)->data==value){
Node *temp = NULL;
temp = q;
if ( p!=NULL){
p->next = q->next;
}else{
(*head) = q->next;
}
q = q->next;
delete temp;
temp = NULL;
++count;
}else{
p = q;
q = q->next;
}
}
}
return count;
}
void DisplayList(Node *head){
if(head!=NULL){
std::cout << head->data << "\n";
while(head->next!=NULL){
std::cout << head->data << "\n";
head =
head->next;
}
std::cout << "\n\n";
}
int main(){
Node *head=NULL;
InsertAfter(&head,10);
InsertAfter(&head,10);
InsertAfter(&head,20);
InsertAfter(&head,10);
DisplayList(head);
DeleteAfter(&head);
DisplayList(head);
int a = DeleteAll(&head,10);
std::cout << "Number Of Nodes deleted
having value 10 = " <<
a <<"\n\n";
DisplayList(head);
return 0;
}