Pop method not giving expected output - c++

I will show a portion of the program that is implementing my pop method for my stack below:
for (int i=0; i<10; i++) // pop 10 times
s1.Pop();
cout << "*pop 10 times\ns1=" << s1 << endl;
cout << "s1.Size()=" << s1.Size() << endl;
cout << "s1.IsEmpty()=" << ((s1.IsEmpty()) ? "T" : "F") << endl;
cout << "s1.IsFull()=" << ((s1.IsFull()) ? "T" : "F") << endl;
cout << "s1.Peek()=" << s1.Peek() << endl;
cout << endl;
Now I will show the pop method that this portion of code is using
T Pop()
{
Node* temp = top;
if(IsEmpty())
{
return NULL;
}
top = temp->link;
return temp->data;
num_items--;
}
The ouput I am getting is almost correct but some of it is off, i will show the output I am getting below:
I will now show the expected output:
To give more clarity, the max size of my list is 30, for some reason my num_items variable is not being decremented, i suspect i need a loop to check for something to decrement but i'm not sure what i should use. I've tried if(top != NULL){} //placing the rest of the code from Node* temp = top; to num_items--; into brackets

return temp->data;
num_items--;
num_items--; will never be executed as it comes after the return statement.

In T Pop():
return temp->data;
num_items--;
The second line will not be executed after you return.

Related

Difficulties implementing sorted Doubly Linked list

I'm taking a class in c++ and one of our assignments is to make an ADT for a linked list and do the implementations.
I've done well so far. But now I'm supposed to add the elements in order.
The code below is my ADD-function and what i've accomplished with this code is to sort them GIVEN that there are only 2 elements in the list. (I'm working with the problem from the basics, and refine my code after).
The while-loop on line 11 is my attempt to iterate (and int t are for debugging)
The problem i have is that my program crash without error (cmd stops working) if i try to add a number greater than 5.
The strange thing here is that if i remove my while-loop, it works. I can't find out whats wrong. So i hope for a little help
Main.cpp:
int main() {
SortedDoublyLinkedList<int> *list = new SortedDoublyLinkedList<int>(5, nullptr, nullptr);
int counter = 0;
while (counter < 2) {
int add;
cout << "Enter number: ";
cin >> add;
list->add(add);
counter++;
cout << counter << endl;
}
cout << list->removeLast()->getData()<< endl;
cout << list->removeLast()->getData()<< endl;
cout << list->removeLast()->getData()<< endl;
return 0;
}
SortedDoublyLinkedList.cpp
template<class T>
DoublyLinkedNode<T> *SortedDoublyLinkedList<T>::add(T val) {
if (isEmpty()) {
head = new DoublyLinkedNode<T>(val);
head->setPrevious(nullptr);
head->setNext(nullptr);
} else {
DoublyLinkedNode<T> *newEl = new DoublyLinkedNode<T>(val);
DoublyLinkedNode<T> *temp = head;
int t = 0;
while(temp->getData() != nullptr){
temp = temp->getNext();
t++;
cout << t << endl;
}
if(newEl->getData() > head->getData()){
newEl->setPrevious(head);
newEl->setNext(nullptr);
head->setNext(newEl);
cout <<"IF"<<endl;
}else{
DoublyLinkedNode<T> *temp = head;
head = newEl;
newEl->setPrevious(nullptr);
newEl->setNext(temp);
temp->setPrevious(head);
cout << "El" << endl;
}
}
numberOfElements++;
return head;
}
This bit of the loop (which I guess is trying to print out the items)... is wrong. The while part loops over the data while it works on elements
Your broken code :
while(temp->getData() != nullptr){
temp = temp->getNext();
t++;
cout << t << endl;
}
Somewhat more functional :
while(temp != nullptr){
cout << t << ":" << temp->getData() << endl;
temp = temp->getNext();
++t;
}
It doesn't solve your sorting problem, but as you said above, you are going iteratively, so I leave that for you to work out.

Print Index of a multilist

I am trying to print the index of a multi linked list. Each node has two elements- a warehouse number and a tool number. I am printing all the tools in each warehouse. I am having a problem with iterating correctly through the list.
I am not getting the correct values and am having trouble finding the problem in my method.
struct Node
{
int WarehouseNumber;
int ToolNumber;
struct Node *n;
}
void showWarehouses()
{
int tempvalue;
bool flag = false;
struct Node *s;
s = start;
if (start == NULL)
{
cout<<"Unable";
return;
}
s->WarehouseN = tempvalue;
cout<<"Warehouse "<<tempvalue<< ": Tool ";
while(s != NULL)
{
if (s->WarehouseN == tempvalue)
{
flag = true;
cout<< s->ToolN <<" ";
s = s->next;
}
}
}
You haven't assigned any values to tempvalue so it causes undefined behavior. Read this post.
Also based on what you have in struct Node and your code, I think you can have something like this picture in the program and you want to print them.
So to top it off I would write something like this code:
void showWarehouses()
{
int tempvalue=1;
bool flag, cont;
struct Node *s;
if (start == NULL)
{
cout << "Unable";
return;
}
cont = true;
while (cont)
{
cont = false, flag = false;
s = start;
while (s)
{
if (s->WarehouseN == tempvalue){
cont = true;
if (!flag){
cout << "Warehouse " << tempvalue << ": Tool ";
flag = true;
}
cout << s->ToolN << " ";
}
s = s->next;
}
cout << endl;
tempvalue++;
}
}
If this:
s = start;
struct Node *s;
compiles, you have an s in a wider scope that just got set to start before being hidden inside showWarehouses by another variable named s. That would be a bad thing.
Anyway, The immediate result is showWarehouses's s is never initialized and it's probably dumb unluck that the program doesn't crash. Since s is not initialized, the rest of the program is printing garbage so the output being wrong is to be expected.
i am assuming that ->warehouseN and ->toolN get the warehouse and tool nums accordingly. This is for right after your if statement.
struct Node *temp;
while (s != NULL){
temp = s;
cout << "Warehouse " << s->warehouseN << ": Tool ";
while (s!= NULL) {
cout << s->toolN << " ";
s = s-> next;
}
s = temp->next;
cout << endl;
}
also, you should probably initiate s before setting it as start

Segfault with initializing an int

/*Matt Boler
meb0054
hw5.cpp
Compile with gcc in cygwin
*/
#import <iostream>
#import <string>
#import <sstream>
#import <cstdlib>
#import <climits>
#import <assert.h>
using namespace std;
//#define UNIT_TESTING
struct TriviaNode
{
string question;
string answer;
int points;
TriviaNode *next;
};
typedef TriviaNode* NodePtr;
//Input: (1) root is the linked list to be added to
// (2) Question is the question for the node to ask
// (3) Answer is the answer to the node's question
// (4) Points is the point value of the node
//This adds a node to the end of the list
void appendNode(NodePtr& root, string question, string answer, int points);
//Input: (1) root is the linked list to get the length of
//Output: Returns the number of nodes in the linked list
//This calculates the number of nodes in a list
int getListLength(NodePtr& root);
//Input: (1) root is the node to start the list from
//This generates a hardcoded trivia list with 3 predefined questions and answers
void generateHardCodedList(NodePtr& root);
//Input: (1) root is the linked list containing questions to be asked
// (2) numQuestions is the number of questions to be asked from the list
//Output: returns o if answered correctly and 1 if answered incorrectly
//This asks the user a question
int askQuestion(NodePtr& root, int numQuestions);
int main()
{
#ifdef UNIT_TESTING
NodePtr head;
cout << "*** This is a debugging version ***" << endl;
cout << "Unit Test Case 1: Ask no questions. The program should give a warning" <<endl;
askQuestion(head, 0);
cout << "Test Case passed..." << endl;
generateHardCodedList(head);
cout << "Unit Test Case 2.1: Ask one question. The tester enters an incorrect answer" << endl;
assert(askQuestion(head, 1) == 1);
cout << "Test Case passed..." << endl;
cout << "Unit Test Case 2.2: Ask one question. The tester enters a correct answer" << endl;
assert(askQuestion(head, 1) == 0);
cout << "Test Case passed..." << endl;
cout << "Unit Test Case 3.1: Ask all questions. The tester enters incorreect answers" << endl;
assert(askQuestion(head, 1) == 1);
assert(askQuestion(head, 2) == 1);
assert(askQuestion(head, 3) == 1);
cout << "Test Case passed..." << endl;
cout << "Unit Test Case 3.2: Ask all questions. The tester enters correect answers" << endl;
assert(askQuestion(head, 1) == 0);
assert(askQuestion(head, 2) == 0);
assert(askQuestion(head, 3) == 0);
cout << "Test Case passed..." << endl;
cout << "Unit Test Case 4: Ask 5 questions in the linked list" << endl;
askQuestion(head, 5);
cout << "*** END OF THE DEBUGGING VERSION ***" << endl;
#else
{
cout << "Welcome to Matt Boler's Trivia Quiz Game!" << endl;
string userContinue = "";
string no = "No";
NodePtr head;
int numQuestions = 3;
generateHardCodedList(head);
while(userContinue.compare(no) != 0)
{
string question, answer;
int score;
cout << "Enter a question:";
getline(cin, question);
cout << "Enter an answer:";
getline(cin, answer);
cout << "Enter award points:";
cin >> score;
cin.clear();
cin.ignore(INT_MAX, '\n');
cout << "Continue? (Yes/No)" << endl;
getline(cin, userContinue);
numQuestions++;
}
//ANYTHING PAST HERE IN THE ELSE BLOCK FAILS VIA SEGFAULT OR JUST NOT RUNNING. NO IDEA WHY
int score = 0;
NodePtr cur = head;
for(int x = 1; x < numQuestions; x++)
{
cur = cur->next;
if(askQuestion(head, x) == 0)
{
score += cur-> points;
}
}
cout << "Your score is: " << score << endl;
}
#endif
return 0;
}
void appendNode(NodePtr& root, string q, string ans, int pts)
{
NodePtr cur;
NodePtr pre;
cur = new TriviaNode;
assert(cur != NULL);
cur->question = q;
cur->answer = ans;
cur->points = pts;
cur->next = NULL;
if (root == NULL)
root = cur;
else
{
pre = root;
while (pre->next != NULL)
{
pre = pre->next;
}
pre->next = cur;
}
}
void generateHardCodedList(NodePtr& root)
{
string q1 = "How long was the shortest war on record? (Hint: how many minutes)";
string ans1 = "38";
int pts1 = 100;
string q2 = "What was the Bank of America's original name? (Hint: Bank of Italy or Bank of Germany)";
string ans2 = "Bank of Italy";
int pts2 = 50;
string q3 = "What is the best-selling video game of all time? (Hint: Call of Duty or Wii Sports)";
string ans3 = "Wii Sports";
int pts3 = 20;
appendNode(root, q1, ans1, pts1);
appendNode(root, q2, ans2, pts2);
appendNode(root, q3, ans3, pts3);
}
int askQuestion(NodePtr& root, int numQuestions)
{
NodePtr cur;
cur = root;
if(numQuestions > getListLength(root))
{
cout << "Warning: there aren't that many questions in the list" << endl;
}
else if(numQuestions < 1)
{
cout << "Warning: the number of trivia to be asked must be greater than or equal to one" << endl;
}
else
{
for(int i = 1; i < numQuestions; i++)
{
cur = cur->next;
}
cout << "Question: " << cur->question << endl;
cout << "Player answer: ";
string player_answer;
getline(cin, player_answer);
cin.clear();
if (player_answer == cur->answer)
{
cout << "Your answer is correct. You recieve " << cur->points << " points." << endl;
return 0;
}
else
{
cout << "Your answer is wrong. The correct answer is: " << cur->answer << endl;
}
}
return 1;
}
int getListLength(NodePtr& root)
{
if(root == NULL)
{
return 0;
}
int count = 0;
NodePtr cur = root;
while(cur != NULL)
{
cur = cur->next;
++count;
}
return count;
}
This is a program to add trivia questions to a linked list in c++. Anything after the while loop causes an error. Specifically, initializing an int causes a segfault; trying to print to console with cout refuses to print anything out.
In the current version of the code your generateHardCodedList pases the root pointer to appendNode functions without initializing it. The calling code did not initialize root (called head in main), generateHardCodedList does not initialize it either, so appendNode receives a garbage pointer as root. After that all bets are off: your program is already broken.
I don't know why in your case it crashes so much later in the code, but it doesn't matter anyway. Your generateHardCodedList call is already broken.
Either initialize your head pointer with nullptr before passing it to generateHardCodedList, or better initialize it to nullptr inside generateHardCodedList, before trying to call appendNode.

Singly linked list , project stops working [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am new to c++ , trying to write singly linked list in c++ , and it's various operations like , print, insert at the end, insert the end, delete etc. I am doing step by step. I have written my first insert method. It is working fine no error , but the first time it goes to the if condition of insert i.e the list is empty and create the first node here the problem is coming is after entering the first node the output screen is closing saying "project has stopped working" . what I am trying to do is after entering one node it should ask "do u wish to add another node?" if users enter "y" it should continue otherwise should go back to main function : Here is my code :
#include <iostream>
using namespace std;
struct node
{
int num;
node *next;
};
class link_list
{
node *head;
node *list;
public:
link_list()
{
head = NULL;
list = NULL;
//cout << list;
}
// void display_options(link_list &b);
void print_list();
void insert();
//void insert_at_beg();
// void insert_at_middle();
};
void link_list::print_list()
{
if (list == NULL)
{
cout << "Empty list" << endl;
//return;
}
else
{
int count = 0;
while (list->next != NULL)
{
list = list->next;
count++;
cout << "Node " << "value " << endl;
cout << count << " " << list->num << endl;
}
}
}
void link_list::insert()
{
// head = new node;
//list = head;
int y;
char a;
do
{
if (head == NULL)
{
head = new node;
cout << "enter the first node" << endl;
cin >> y;
list->num = y;
list->next = NULL;
}
else
{
node * newNode;
list == head;
while (list->next != NULL)
{
list->next = list;
}
newNode = new node;
cin >> y;
newNode->num = y;
list->next = newNode;
newNode->next = NULL;
}
cout << "do u wish to add another node?" << endl;
cin >> a;
} while (a == 'y' || a == 'Y');
}
int main()
{
link_list ll;
char choice;
do{
cout << "select one" << endl;
cout << "press 1 for insert ." << endl;
cout << "press 2 for insert at beginning ." << endl;
cout << "press 3 for insert at the middle ." << endl;
cout << "press 4 delete ." << endl;
cout << "print 5 print the linked list :" << endl;
cout << "print 6 exit :" << endl;
int no;
cin >> no;
switch (no)
{
case 1:
ll.insert();
break;
case 5:
ll.print_list();
case 6:
return 0;
default:
cout << "oops wrong choice" << endl;
}
fflush(stdin);
cout << "Do u wanna make another choice?" << endl;
cin >> choice;
cout << choice << endl;
} while (choice == 'Y' || choice == 'y');
cout << "Thanks!" << endl;
system("pause");
return 0;
}
You need to keep a more careful eye on your compiler warnings, and you need to learn how to use a debugger. There are many problems with this code, but most of them are easy to find by debugging.
This line in link_list::insert is not an assignment, it is a comparison. This would likely be raised as a compiler warning in most modern compilers. You'll probably want to fix that.
line == head
This loop doesn't do anything useful:
while (list->next != NULL)
{
list->next = list;
}
If list starts off as non-null, all this code will do is loop forever, repeatedly setting list->next to list. You probably wanted the operation to be the other way around.
list = list->next;
which will get you the last element in the list.
Still in the same function, this is broken:
head = new node;
cout << "enter the first node" << endl;
cin >> y;
list->num = y;
list->next = NULL;
because you haven't initialised list. Using head instead of list is probably what you wanted.
This is silly:
newNode = new node;
cin >> y;
because you don't prompt for the node value.
Once these changes are made, the code appears to function, at least for insertion and printing, but I'm not going to investigate further.
Perhaps this might be better moved to https://codereview.stackexchange.com/
head = new node;
cout << "enter the first node" << endl;
cin >> y;
list->num=y; //<-- problem
You are using list without initializing it. You should write
list = head;
before the statement list->num=y;
This will fix the bug for first time insertion. but there are several other problems in you code while inserting subsequently, which is pointed out by other answers. Modified code will be
void link_list::insert()
{
int y;
char a;
do
{
if (head == NULL)
{
head = new node;
cout << "enter the first node" << endl;
cin >> y;
head->num = y;
head->next = NULL; // no need to list as a member at all
}
else
{
node* list = head;
while (list->next != NULL)
{
list= list->next;
}
list->next= new node;
cin >> y;
list->next->num = y;
list->next->next = NULL;
}
cout << "do u wish to add another node?" << endl;
cin >> a;
} while (a == 'y' || a == 'Y');
}
void link_list::print_list()
{
if (head == NULL)
{
cout << "Empty list" << endl;
//return;
}
else
{
int count = 0;
node* list=head;
while (list->next != NULL)
{
count++;
cout << "Node " << "value " << endl;
cout << count << " " << list->num << endl;
list = list->next;
}
}
}

Seg Fault at return statement in function

My program is supposed to convert a prompt from infix to postfix. So far, through a debugger and various other methods, I have located the exact point at which I segfault, but don't understand why.
Here's my code:
Here's itop.h:
using namespace std;
#include <cstdlib>
#include <iostream>
class sNode{
public:
char data;
sNode *next;
};
class stack{
public:
sNode *head;
void push (char);
sNode pop();
int rank(char);
stack()
{
cout << "Initiliazing stack." << endl;
}
};
This is my itop.cpp file:
#include "itop.h"
void stack::push (char a)
{
// cout << "Pushing " << a << endl;
sNode *sn;
sn = new sNode;
sn->data = a;
sn->next = head;
head = sn;
}
sNode stack::pop()
{
// cout << "Popping stack." << endl;
sNode *sn;
sn = head;
head = head->next;
return *sn;
}
int stack::rank(char x)
{
int num = 0;
// cout << "Checking rank." << endl;
if(x == '\0')
{
num = 1;
// cout << "Checking for null" << endl;
return num;
}
else if(x == '+' || x == '-')
{
num = 2;
// cout << "Checking if + or -" << endl;
return num;
// cout << "After return." << endl;
}
else if(x == '*' || x == '/')
{
num = 3;
// cout << "Checking for * or /" << endl;
return num;
}
else
cout << "Error! Input not valid!" << endl;
}
And here's main.cpp:
using namespace std;
#include <iostream>
#include <cstdlib>
#include <cstring>
#include "itop.h"
int main()
{
char *temp1; //Instantiating variables.
char *temp2;
temp1 = new char[20];
temp2 = new char [20];
stack s;
do //Checking commands.
{
cout << "infix_to_postfix> ";
cin >> temp1;
if(strcmp(temp1, "quit") == 0)
{
return 0;
}
if(strcmp(temp1, "convert") != 0)
{
cout << "Error! Invalid command." << endl;
}
cin >> temp2;
if(strcmp(temp1, "convert") == 0)
{
for(int i=0; i<sizeof(temp2); i++)
{
if(isdigit(temp2[i]))
{
cout << atoi(&temp2[i]);
}
else if(s.rank(temp2[i]) < s.rank(s.head->data))
{
sNode temp = s.pop();
cout << temp.data;
}
else
{
s.push(temp2[i]);
}
}
}
else
{
cout << "Error! Command not supported." << endl;
}
}while(strcmp(temp1, "quit") != 0);
return 0;
}
The function is called at
else if(s.rank(temp2[i]) < s.rank(s.head->data))
And the problem is in here:
else if(x == '+' || x == '-')
{
num = 2;
// cout << "Checking if + or -" << endl;
return num;
// cout << "After return." << endl;
}
Specifically right before return num, I get "Segmentation fault (core dumped)" error message. I have used gdb and all I know is that right after "Checking if + or -" I see "$1 = 2". I'm not quite sure what that means, but it is what I want to return.
Thank you for your help.
There are many mistakes in your code. Your stack implementation is wrong. push() for example only sets head over and over again. This results in your stack class being able to ever only hold one element. next is never set to anything, so it contains random garbage. Further down, you have this:
for(int i=0; i<sizeof(temp2); i++)
sizeof(temp2) does not give you the amount of characters of the string temp2 points to. It gives you the size of the pointer temp2 itself. Furthermore, you end up reading s.head from an empty stack, which will be a pointer to random garbage. At that point, all bets are off of course. You can't expect anything else than a crash and burn.
Fix 1:Write a proper constructor.
stack()
{
head=NULL;
cout << "Initiliazing stack." << endl;
}
Fix 2:Write an extra method to check if stack is empty.
int stack::empty()
{
if(head == NULL)
return true;
else
return false;
}
Fix 3:Check if stack empty before using the stack data.
else if(!s.empty() && s.rank(temp2[i]) < s.rank(s.head->data))
{
...
}
Fix 4: Fix the rest of the code logic.