Runtime polymorphism and operator overload - c++

The problem is that in main function pointer to abstract class list calls operator+ of this class. But how can I call overloaded operators from child classes (queue and stack) with pointer to parent class list
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
class list
{
public:
list* head;
list* tail;
list* next;
int num;
virtual ~list() {}
list() { head = tail = next = NULL; num = 0; }
virtual list operator+(int i) { return *this; };
virtual int operator-() { return 0; };
};
class queue : public list
{
public:
list operator+(int i);
int operator-();
};
class stack : public list
{
public:
list operator+(int i);
int operator-();
};
int main()
{
srand(time(NULL)); rand();
list* p;
queue q_ob;
stack s_ob;
char ch;
for (;;)
{
cout << "Enter something else to stop.\nStack, Queue or ULL? (S/Q): \n";
cin >> ch;
ch = tolower(ch);
if (ch == 'q')
p = &q_ob;
else if (ch == 's')
p = &s_ob;
else break;
p + (rand() % 100);
}
cout << "Enter T to terminate\n";
for (;;)
{
cout << "Remove from Stack, Queue or ULL? (S/Q):";
cin >> ch;
ch = tolower(ch);
if (ch == 'q')
p = &q_ob;
else if (ch == 's')
p = &s_ob;
else break;
cout << -(*p) << '\n';
}
return 0;
}
list queue::operator+(int i)
{
list* item;
item = new queue;
if (!item)
{
cout << "Allocation error.\n";
exit(1);
}
item->num = i;
// put on end of list:
if (tail)
tail->next = item;
tail = item;
item->next = NULL;
if (!head)
head = tail;
return *this;
}
int queue::operator-()
{
int i;
list* p;
if (!head)
{
cout << "List empty.\n";
return 0;
}
// remove from start of list
i = head->num;
p = head;
head = head->next;
delete p;
return i;
}
list stack::operator+(int i)
{
list* item;
item = new stack;
if (!item)
{
cout << "Allocation error.\n";
exit(1);
}
item->num = i; // put on front of list
// for stack - like operation
if (head)
item->next = head;
head = item;
if (!tail)
tail = head;
return *this;
}
int stack::operator-()
{
int i;
list* p;
if (!head)
{
cout << "List empty.\n";
return 0;
}
// remove from start of list:
i = head->num;
p = head;
head = head->next;
delete p;
return i;
}

Related

Program.exe has triggered a breakpoint in destructor of linked list class

When I run my program, everything works as expected until the destructor of the LList class. On the line that says delete current;, I get the following error:
BlankConsoleLab.exe has triggered a breakpoint.
I have been trying to solve this issue for a long time. I would appreciate it if perhaps someone could try to point out what I am doing wrong here.
Below is my code for the program. Thank you
Linked List Class
class LList
{
private:
Node* head;
Node* tail;
int size = 0;
public:
LList()
{
head = nullptr;
tail = nullptr;
size = 0;
}
LList(Node* h, Node* t)
{
this->head = h;
this->tail = t;
}
~LList()
{
Node* current = head;
while (current != nullptr) {
Node* next = current->m_next;
delete current;
current = next;
}
}
void print()
{
//temporary node pointer to traverse through the linked list
Node* temp = head;
cout << endl << "<MY LINKED LIST>\n";
while (temp != nullptr)
{
cout << temp->m_data.firstName << " ";
cout << temp->m_data.lastName << " ";
cout << temp->m_data.hrWage << " ";
cout << temp->m_data.hrWork << " " << endl;
temp = temp->m_next;
}
cout << endl;
}
void removeFirst()
{
//case 1: linked list is empty (never enters loop)
//case 2: linked list is not empty
if (head != nullptr)
{
Node* temp = head;
head = head->m_next;
delete temp;
//decrease size tracker of the linked list
size--;
}
}
void removeLast()
{
//case 1: linked list is empty (never enters loop)
//case 2: linked list has one node
if (head->m_next == nullptr)
{
removeFirst();
}
//case 3: linked list has more than one node
else if (head != nullptr)
{
Node* cur = head;
Node* prev = nullptr;
while (cur->m_next != nullptr)
{
prev = cur;
cur = cur->m_next;
}
tail = prev;
tail->m_next = nullptr;
delete cur;
//decrease size tracker of the linked list
size--;
}
}
//void removeAt(int pos)
//{
// //Case 1: input is invalid (less than 1 or greater than size)
// if (pos < 1 && pos > size)
// {
// return;
// }
// //Case 2: input is position 1
// else if (pos == 1)
// {
// removeFirst();
// }
// //Case 3: input is the last position (input equals size)
// else if (pos == size)
// {
// removeLast();
// }
// //Case 4: input is valid, and not 1 or last position (greater than 1 and less than size)
// else if (head != nullptr)
// {
// Node* cur = head;
// Node* prev = nullptr;
// for (int i = 1; i < pos; i++)
// {
// prev = cur;
// cur = cur->m_next;
// }
// prev->m_next = cur->m_next;
// delete cur;
// size--;
// }
//}
Node* swap(Node* lh, Node* rh)
{
Node* temp = rh->m_next;
rh->m_next = lh;
lh->m_next = temp;
return rh;
}
void readBin()
{
ifstream file;
file.open("C:\\Users\\there\\source\\repos\\cst126-lab9-JEmersonLawrance\\BlankConsoleLab\\Employee Data.bin", ios::binary);
if (file)
{
Node* cur = head;
Node* prev = nullptr;
for (int i = 0; i < 4; i++)
{
file.read((char*)&cur->m_data.firstName, sizeof(cur->m_data.firstName));
file.read((char*)&cur->m_data.lastName, sizeof(cur->m_data.lastName));
file.read((char*)&cur->m_data.hrWage, sizeof(cur->m_data.hrWage));
file.read((char*)&cur->m_data.hrWork, sizeof(cur->m_data.hrWork));
prev = cur;
cur = cur->m_next;
}
return;
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
void writeBin()
{
ofstream file;
file.open("Employee Data Output.bin", ios::binary);
if (file)
{
Node* cur = head;
Node* prev = nullptr;
while (cur != nullptr)
{
file.write((char*)&cur->m_data.firstName, sizeof(cur->m_data.firstName));
file.write((char*)&cur->m_data.lastName, sizeof(cur->m_data.lastName));
file.write((char*)&cur->m_data.hrWage, sizeof(cur->m_data.hrWage));
file.write((char*)&cur->m_data.hrWork, sizeof(cur->m_data.hrWork));
prev = cur;
cur = cur->m_next;
}
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
};
Node Class
class Node
{
public:
Employee m_data;
Node* m_next;
Node()
{
m_data.firstName = "";
m_data.lastName = "";
m_data.hrWage = 0;
m_data.hrWork = 0;
m_next = nullptr;
}
Node(Node* next)
{
m_data.firstName = "";
m_data.lastName = "";
m_data.hrWage = 0;
m_data.hrWork = 0;
m_next = next;
}
Node(const Node& copy)
{
m_data.firstName = copy.m_data.firstName;
m_data.lastName = copy.m_data.lastName;
m_data.hrWage = copy.m_data.hrWage;
m_data.hrWork = copy.m_data.hrWork;
}
Node operator = (const Node& copy)
{
m_data.firstName = copy.m_data.firstName;
m_data.lastName = copy.m_data.lastName;
m_data.hrWage = copy.m_data.hrWage;
m_data.hrWork = copy.m_data.hrWork;
return *this;
}
~Node()
{
}
};
Employee Class
struct Employee
{
public:
string firstName;
string lastName;
int hrWage;
int hrWork;
Employee()
{
firstName = "";
lastName = "";
hrWage = 0;
hrWork = 0;
}
Employee(string first, string last, int wage, int work)
{
firstName = first;
lastName = last;
hrWage = wage;
hrWork = work;
}
~Employee()
{
}
void getInput()
{
for (int i = 0; i < 4; i++)
{
cout << "EMPLOYEE # " << i+1 << ":\n" << endl;
cout << "First name: ";
cin >> this[i].firstName;
cout << "Last name: ";
cin >> this[i].lastName;
cout << "Hourly Wage: ";
cin >> this[i].hrWage;
cout << "Hours Worked: ";
cin >> this[i].hrWork;
}
}
void writeBin()
{
ofstream file;
file.open("C:\\Users\\there\\source\\repos\\cst126-lab9-JEmersonLawrance\\BlankConsoleLab\\Employee Data.bin", ios::binary);
if (file)
{
for (int i = 0; i < 4; i++)
{
file.write((char*)&this[i].firstName, sizeof(this[i].firstName));
file.write((char*)&this[i].lastName, sizeof(this[i].lastName));
file.write((char*)&this[i].hrWage, sizeof(this[i]).hrWage);
file.write((char*)&this[i].hrWork, sizeof(this[i]).hrWork);
}
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
};
Main Function
int main()
{
cout << "In this program, LIST will read the user information"
<< " in from a binary file, and output it into a different binary"
<< " file.\n" << endl;
Employee data[4];
data->getInput();
data->writeBin();
//creating linked list
Node fourth;
Node third(&fourth);
Node second(&third);
Node first(&second);
LList LIST(&first, &fourth);
LIST.readBin();
LIST.writeBin();
LIST.print();
return 0;
}
In main(), you are constructing your LIST object with pointers to local Node objects that are created in automatic memory within main()'s call frame. When main() exits, all of its local variables are destroyed automatically. But, when the LIST object is destroyed, its destructor tries to call delete on those Node objects which were not created in dynamic memory with new. Thus, your code exhibits undefined behavior.

Why is this code for single linked list not working?

Being a beginner I tried this single linked list program to accept and display first to last elements.I can't figure out what is wrong.After you run it the program stops responding after taking in the first element. I am not very familiar with the language and am new to pointer concept. This was an assignment work.
#include <iostream>
using namespace std;
struct node
{
int data;
node* next;
};
class alpha
{
public:
node* head;
node* last;
node* n;
node* p;
int x;
char ch;
void input()
{
cout << "Enter the element..";
cin >> x;
insert(x);
cout << "Do you want to add more?";
cin >> ch;
if (ch == 'y')
{
input();
}
else
{
display();
}
}
void insert(int x1)
{
n = new node;
n->data = x1;
if (head == NULL)
{
head = n;
last = n;
}
else
{
n->next = NULL;
last->next = n;
last = n;
}
}
void display()
{
p = head;
while (p != NULL)
{
cout << p->data;
p = p->next;
}
}
};
int main()
{
alpha o;
o.input();
return 0;
}
the big mistake already pointed out is the absence of an initialization by a constructor. Also I suggest to move some data member to private, and make some of them local.
#include <iostream>
using namespace std;
struct node
{
int data;
node* next;
};
class alpha
{
private:
node* head;
node* last;
public:
alpha() {
head = NULL;
last = NULL;
}
void input()
{
int x;
char ch;
cout << "Enter the element..";
cin >> x;
insert(x);
cout << "Do you want to add more?";
cin >> ch;
if (ch == 'y')
{
input();
}
else
{
display();
}
}
void insert(int x1)
{
node* n = new node;
n->data = x1;
if (head == NULL)
{
head = n;
last = n;
}
else
{
n->next = NULL;
last->next = n;
last = n;
}
}
void display()
{
node* p = head;
while (p != NULL)
{
cout << p->data;
p = p->next;
}
}
};
int main()
{
alpha o;
o.input();
return 0;
}
As someone suggested, please implement a destructor ~alpha(), in order to avoid leaks of node instances.

How to delete node from linked list?

Adding integers to list works fine, but there's something wrong with deleting and printing.
I'm not friendly with debugger yet, but I found out that there is error from node pointer 'first'. Its value is -17891602. I don't know what happened...
#include <iostream>
using namespace std;
class nodeList;
class node {
friend class nodeList;
private:
int data;
node* link;
public:
node() { //constructor
data = 0;
link = NULL;
}
node(int d) { //constructor
data = d;
link = NULL;
}
node(int d, node* l){ //constructor
data = d;
link = l;
}
};
class nodeList {
private:
node* first;
int num = 0;
node* nt;
public:
nodeList() {
first = new node();
}
node* end(node* t){ //return pointer of last element
t = first;
for (int i = 0; i < num; i++){
t = t->link;
}
return t;
}
void add(int a){ //add 'a' at the end of the list
node* x = new node(a);
node* y = this->end(nt);
y->link = x;
num++;
}
void del(int n){ //n : data of element that you want to delete from list
node* temp = first;
node* pretemp = NULL;
node* x;
int i;
for (i = 0; i <= this->num; i++){ //loop to find 'n'
pretemp = temp;
temp = temp->link;
if (n == temp->data){
break;
}
}
temp = first;
for (int j = 0; j<i; j++){ //i : where 'n' is,
temp = temp->link;
}
x = temp->link;
pretemp->link = x;
delete temp;
num--;
}
void printList(){
node* temp = first;
temp = temp->link;
for (int i = 0; i<this->num; i++){
cout << temp->data << endl;
temp = temp->link;
}
}
};
int main(){
nodeList *l = new nodeList();
int a;
int select;
while (1){
cout << "1. ADD 2. DELETE 3. PRINT" << endl;
cin >> select;
if (select == 1){
cout << "Enter an integer: ";
cin >> a;
if (cin.fail()) {
cout << "Wrong input" << endl;
break;
}
l->add(a);
l->printList();
}
if (select == 2){
cout << "Enter the data of the element you want to delete: ";
cin >> a;
if (cin.fail()) {
cout << "Wrong input" << endl;
break;
}
l->del(a);
l->printList();
}
if (select == 3){
l->printList();
}
}
}
Your del function deletes pretemp node (node that was before the one that you need to delete).
Here's possible fix:
//n : data of element that you want to delete from list
void del(int n)
{
//loop to find 'n'
for (node *tmp = first; tmp->link; tmp = tmp->link)
{
if (n == tmp->link->data)
{
node *x = tmp->link;
tmp->link = tmp->link->link;
delete x;
num--;
break;
}
}
}
Also, was your del supposed to delete all nodes with data == n?
These functions are a bit complicated. Here is a simpler idea:
void del(int n){
node* pretemp = first, *temp = first->link;
if(pretemp->data == n) { //handle the deleting of the first node
first = first->link;
delete pretemp;
return;
}
while(temp != NULL && temp->data != n) { //find the node with the data member "n"
pretemp = temp;
temp = temp->link;
}
if(temp != NULL) { //if you found the node, delete it
pretemp->link = temp->link;
delete temp;
}
--num;
}
Your code is a bit over-complicated for what it needs.
Try something more like this instead:
#include <iostream>
#include <limits>
using namespace std;
class nodeList;
class node
{
friend class nodeList;
private:
int data;
node* link;
public:
node(int d = 0) //constructor
: data(d), link(NULL)
{
}
};
class nodeList
{
private:
node* first;
int num;
public:
nodeList()
: first(NULL), num(0)
{
}
~nodeList()
{
node *n = first, *t;
while (n)
{
t = n->link;
delete n;
n = t;
}
}
void add(int data) //add 'data' at the end of the list
{
node* n = new node(data);
if (!first)
first = n;
else
{
node *t = first;
while (t->link)
t = t->link;
t->link = n;
}
++num;
}
void del(int data) //data : data of element that you want to delete from list
{
node* n = first;
node* prev = NULL;
while (n) //loop to find 'data'
{
if (data == n->data)
{
if (prev)
prev->link = n->link;
if (n == first)
first = n->link;
delete n;
--num;
return;
}
prev = n;
n = n->link;
}
}
void printList()
{
for(node* n = first; n != NULL; n = n->link)
cout << n->data << endl;
}
};
int main()
{
nodeList l;
int input;
bool keepGoing = true;
do
{
cout << "1. ADD 2. DELETE 3. PRINT 4. EXIT" << endl;
if (!(cin >> input))
{
cout << "Wrong input" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
}
else
{
switch (input)
{
case 1:
cout << "Enter an integer: ";
if (!(cin >> input))
{
cout << "Wrong input" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
}
else
{
l.add(input);
l.printList();
}
break;
case 2:
cout << "Enter the data of the element you want to delete: ";
if(!(cin >> input))
{
cout << "Wrong input" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
}
else
{
l.del(input);
l.printList();
}
break;
case 3:
l.printList();
break;
case 4:
keepGoing = false;
break;
default:
cout << "Wrong input" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
break;
}
}
}
while (keepGoing);
return 0;
}
If you add an extra node* member to your nodeList class, you can simplify and speed up your add() method:
class nodeList
{
private:
node* first;
node* last;
int num;
public:
nodeList()
: first(NULL), last(NULL), num(0)
{
}
~nodeList()
{
node *n = first, *t;
while (n)
{
t = n->link;
delete n;
n = t;
}
}
void add(int data) //add 'data' at the end of the list
{
node* n = new node(data);
if (!first)
first = n;
if (last)
last->link = n;
last = n;
++num;
}
void del(int data) //data : data of element that you want to delete from list
{
node* n = first;
node* prev = NULL;
while (n) //loop to find 'data'
{
if (data == n->data)
{
if (prev)
prev->link = n->link;
if (n == first)
first = n->link;
if (n == last)
last = prev;
delete n;
--num;
return;
}
prev = n;
n = n->link;
}
}
void printList()
{
for(node* n = first; n != NULL; n = n->link)
cout << n->data << endl;
}
};
And if you can change your list to be a double-linked list instead of a single-linked list, you can simplify your del() method as well:
#include <iostream>
#include <limits>
using namespace std;
class nodeList;
class node
{
friend class nodeList;
private:
int data;
node* prev;
node* next;
public:
node(int d = 0) //constructor
: data(d), prev(NULL), next(NULL)
{
}
};
class nodeList
{
private:
node* first;
node* last;
int num;
public:
nodeList()
: first(NULL), last(NULL), num(0)
{
}
~nodeList()
{
node *n = first, *t;
while (n)
{
t = n->next;
delete n;
n = t;
}
}
void add(int data) //add 'data' at the end of the list
{
node* n = new node(data);
if (!first)
first = n;
if (last)
last->next = n;
n->prev = last;
last = n;
++num;
}
void del(int data) //data : data of element that you want to delete from list
{
for(node* n = first; n != NULL; n = n->next) //loop to find 'data'
{
if (data == n->data)
{
if (n->prev)
n->prev->next = n->next;
if (n->next)
n->next->prev = n->prev;
if (n == first)
first = n->next;
if (n == last)
last = n->prev;
delete n;
--num;
return;
}
}
}
void printList()
{
for(node* n = first; n != NULL; n = n->next)
cout << n->data << endl;
}
};

Output of c++ program not coming as expected

I have made a C++ program for a binary tree. But the terminal is not asking the statement for inputting the direction for where the elements are to be placed.
Also when I replace the statement from " node *temp = new node " to "node *temp=NULL" the program stops working .
#include <iostream>
#include <cstring>
using namespace std;
class node {
int data;
node * left;
node * right;
public:
node * level_order(node * first);
node * create_bt(node * first);
void display(node * first);
};
//node *first=NULL;
node * node::create_bt(node * first) {
node * temp = new node;
int ele;
//char dir;
cout << "\n Enter data ";
cin >> ele;
temp->data = ele;
temp->left = NULL;
temp->right = NULL;
if (first == NULL) {
temp = first;
return first;
} else {
char dir[20];
cout << "\n Enter the direction ";
cin >> dir;
node * cur = first;
int j = 0;
while (dir[j] != '\0') {
if (dir[j] == 'l') {
cur = cur->left;
}
if (dir[j] == 'r') {
cur = cur->right;
}
j++;
}
cur = temp;
return first;
}
}
void node::display(node * first) {
if (first == NULL)
return;
cout << "\n " << first->data;
display(first->left);
display(first->right);
}
int main() {
int n;
node s;
node * first = NULL;
cout << "\n No of elements ";
cin >> n;
for (int i = 0; i < n; i++) {
first = s.create_bt(first);
}
s.display(first);
return 0;
}
first=s.create_bt(first); does not changes state, from NULL to 'l' or 'r'. You have to change that.
node*node::create_bt(node *first)
{
node *temp=new node;
int ele;
//char dir;
cout<<"\n Enter data ";
cin>>ele;
temp->data=ele;
temp->left=NULL;
temp->right=NULL;
char dir[20];
cout<<"\n Enter the direction ";
cin>>dir;
if(first==NULL)
{
temp=first;
return first;
}
else
{
node*cur=first;
int j=0;
while(dir[j]!='\0')
{
if(dir[j]=='l')
{
cur=cur->left;
}
if(dir[j]=='r')
{
cur=cur->right;
}
j++;
}
cur=temp;
return first;
}
}
I believe you re looking something like this. This is a basic binary tree, i had to make a basic one in order to understand how it works and how it chooses left and right. I make a class inside a class, in order to have access to my data members (node class, int data, *left , *right) and have them at the same time protected, all-in-one. As you can see "newnode" just creates a node and NULL s the pointers. Thats it. "Find" searches and finds a node with a current key, and returns it when exits. All the rest, i guess, you can understand them, as they are prety much the same with your code. The only thing you have to do is to define, when you want to direct the node you want. REMINDER: You have to find a way to utilize it, so the leafs will not end far-left or far-right.("Enter the direction"). I hope i helped you understand.
#include <iostream>
#include <conio.h>
using namespace std;
class mybTree {
class node {
public:
int data;
node * left;
node *right;
};
node *root;
node *newnode(int num){
node *newnode1;
newnode1 = new (nothrow) node;
newnode1->data = num;
newnode1->left = NULL;
newnode1->right = NULL;
return newnode1;
}
public:
node *find (int key) {
node *current;
current = root;
while (current->data !=key){
if (key<current->data){
current = current->left;
} else {
current = current->right;
}
if (current == NULL){
return NULL;
}
}
return NULL;
}
void display (node *ptr);
void display_tree();
bool insert(int num);
void post_order_delete(node *ptr);
mybTree();
~mybTree();
};
int main(){
char ch = ' ';
int a;
mybTree mybTree1;
while (ch !='0'){
cout << "0->Exit"<<endl<< "1-> add"<<endl<< "2-> find" <<endl<<"3-> Show me the tree\n";
ch = getch();
switch (ch) {
case '0':
break;
case '1':
cout << "number";
cin >> a;
if (!mybTree1.insert(a)){
cout << "Not enough memory" << endl;
}
break;
case '2' :
cout << "Number:" ;
cin >> a;
if (mybTree1.find(a)!=NULL) {
cout << "Found" << endl;
} else {
cout << "Not existed" << endl;
}
break;
case '3':
mybTree1.display_tree();
cout<<endl;
break;
default:
cout << "Wrong Message";
break;
}
}
return 0;
}
void mybTree::display(node *ptr) {
if (ptr == NULL){
return;
}
display(ptr->left);
cout << ptr->data<<endl;
display(ptr->right);
}
void mybTree::display_tree() {
//Displays the Tree
display(root);
}
bool mybTree::insert(int num) {
//It inserts a node. Desides left or right.
node *next,*current,*ptr;
int isleft;
next = current = root;
ptr = newnode(num);
if (ptr == NULL) {
return false;
}
if (root == NULL) {
root = ptr;
return true;
}
while (1){
if (num < current->data){
next = current->left;
isleft = 1;
} else {
next = current->right;
isleft = 0;
}
if (next == NULL){
if (isleft){
current->left = ptr;
} else {
current->right = ptr;
}
return true;
}
current=next;
}
return false;
}
void mybTree::post_order_delete(node *ptr) {
//deletes the node. Usefull for destructor
if (ptr == NULL){
return;
}
post_order_delete(ptr->left);
post_order_delete(ptr->right);
cout << ptr->data;
delete ptr;
}
mybTree::mybTree() {
//Constructor
root = NULL;
}
mybTree::~mybTree() {
//Destructor
post_order_delete(root);
root = NULL;
}

Logical Error in Program

I tried using cout at various stages to figure but in vain. The program crashes after flushing the first two values in the reversed list. It prints a garbage value as the third value and before it can print the last two values, it crashes.
#include <iostream>
using namespace std;
class LLStack {
public:
struct Node {
int data;
Node* next;
Node(int n) {
data = n;
next = 0;
}
Node(int n, Node* node) {
data = n;
next = node;
}
};
LLStack();
LLStack(const LLStack&);
LLStack& operator = (const LLStack&);
~LLStack();
void push(int);
int pop();
int top();
bool isEmpty();
void flush();
private:
Node* head;
};
LLStack::LLStack() {
head = 0;
}
LLStack::LLStack(const LLStack& s) {
head = new Node(NULL);
head->data = s.head->data;
if (s.head->next != NULL) {
head->next = new Node(*(s.head->next));
}
else {
head->next = new Node(NULL);
}
}
LLStack::~LLStack() {
this->flush();
}
LLStack& LLStack::operator = (const LLStack& s) {
this->head = new Node(NULL);
this->head->data = s.head->data;
if (s.head->next != NULL) {
this->head->next = new Node(*(s.head->next));
}
else {
this->head->next = new Node(NULL);
}
return *this;
}
void LLStack::push(int x) {
if (head == 0) head = new Node(x);
else {
Node* temp = new Node(x, head);
head = temp;
}
}
int LLStack::pop() {
if (head == 0) {
cout << "\n\nNo elements to pop\n\n";
return -1;
}
else {
Node* temp = head;
int n = temp->data;
head = temp->next;
delete temp;
return n;
}
}
int LLStack::top() {
if (head == 0) {
cout << "\n\nNo elements in the stack\n\n";
return -1;
}
else {
return head->data;
}
}
bool LLStack::isEmpty() {
return (head == 0);
}
void LLStack::flush() {
if (head == 0) {
cout << "\n\nNo elements in the Stack to flush\n\n";
return;
}
cout << "\n\nFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
delete temp;
}
cout << endl << endl;
}
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
int main() {
LLStack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
reverseStack(s);
cout << "\n\nFlushing s:\n";
s.flush();
return 0;
}
I tried using cout at various stages to figure but in vain. The program crashes after flushing the first two values in the reversed list. It prints a garbage value as the third value and before it can print the last two values, it crashes.
#include <iostream>
using namespace std;
class LLStack {
public:
struct Node {
int data;
Node* next;
Node(int n) {
data = n;
next = 0;
}
Node(int n, Node* node) {
data = n;
next = node;
}
};
LLStack();
LLStack(const LLStack&);
LLStack& operator = (const LLStack&);
~LLStack();
void push(int);
int pop();
int top();
bool isEmpty();
void flush();
private:
Node* head;
};
LLStack::LLStack() {
head = 0;
}
LLStack::LLStack(const LLStack& s) {
head = new Node(NULL);
head->data = s.head->data;
if (s.head->next != NULL) {
head->next = new Node(*(s.head->next));
}
else {
head->next = new Node(NULL);
}
}
LLStack::~LLStack() {
this->flush();
}
LLStack& LLStack::operator = (const LLStack& s) {
this->head = new Node(NULL);
this->head->data = s.head->data;
if (s.head->next != NULL) {
this->head->next = new Node(*(s.head->next));
}
else {
this->head->next = new Node(NULL);
}
return *this;
}
void LLStack::push(int x) {
if (head == 0) head = new Node(x);
else {
Node* temp = new Node(x, head);
head = temp;
}
}
int LLStack::pop() {
if (head == 0) {
cout << "\n\nNo elements to pop\n\n";
return -1;
}
else {
Node* temp = head;
int n = temp->data;
head = temp->next;
delete temp;
return n;
}
}
int LLStack::top() {
if (head == 0) {
cout << "\n\nNo elements in the stack\n\n";
return -1;
}
else {
return head->data;
}
}
bool LLStack::isEmpty() {
return (head == 0);
}
void LLStack::flush() {
if (head == 0) {
cout << "\n\nNo elements in the Stack to flush\n\n";
return;
}
cout << "\n\nFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
delete temp;
}
cout << endl << endl;
}
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
int main() {
LLStack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
reverseStack(s);
cout << "\n\nFlushing s:\n";
s.flush();
return 0;
}
Please run it and you'll understand for yourself.
The problem is in function:
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
Here you are creating the local stack "s2". When the s2 goes out of scope, it calls the destructor and flushes the whole stack. Better you should remove the flush call from destructor or create the global "s2". Best option will be implement the other logic to reverse the stack.