working on a simple C++ pointer-based stack program. I am attempting to print a string which is part of the NameItem class which the PointerStack class uses as its item type (see code). Whenever I try to print the string in the main() function of my program, the console prints gibberish and beeps repeatedly. However, when I call the PrintPointerStack function, there are no errors and everything prints as expected.
I’d tried changing the classes, rearranging the code, and while I can pinpoint which line generates the error I can’t figure out why. I’m completely lost here, never seen anything like this before, so I’m sorry if the answer is simple and found in a google search but I’ve been going for hours and just don’t know what to search anymore.
Code is below:
#include <iostream>
#include <string>
#include <stack>
#include <cstddef>
#include <new>
using namespace std;
#include "NameItem.cpp"
#include "Stack.cpp"
#include "PointerStack.cpp"
void PrintPointerStack(PointerStack printer){
NameItem temp;
while(!printer.IsEmpty()){
temp = printer.Top();
printer.Pop();
temp.Print();
}
cout << endl;
}
int main(){
string initNames[] = {"Michael","Charlie","Susan","Alexa",
"Jason","Candice","Beatrice","Lois",
"Peter","Matthew"};
int initNamesLen = 10;
PointerStack PStacker, tempPStacker;
NameItem filler;
for(int i = 0; i < initNamesLen; i++){
filler.Init(initNames[i]);
PStacker.Push(filler);
}
cout << endl << "---------- Pointer-based Stack ----------" << endl << endl;
PrintPointerStack(PStacker);
cout << "Top: ";
(PStacker.Top()).Print(); //This is where the program errors. I've tried creating a
//temp variable like in the function above, and I've
//tried accessing the string directly and printing it
//from main() using cout, which produce the same results.
//So the error is caused specifically by the cout <<
//string statement, when I try to use that statement
//within the bounds of the main function.
cout << endl;
PrintPointerStack(PStacker);
cout << endl << "Popped: ";
(PStacker.Top()).Print();
PStacker.Pop();
(PStacker.Top()).Print();
PStacker.Pop();
cout << endl;
PrintPointerStack(PStacker);
cout << endl << "Pushed: Sammy Valerie" << endl;
filler.Init("Sammy");
PStacker.Push(filler);
filler.Init("Valerie");
PStacker.Push(filler);
PrintPointerStack(PStacker);
try{
PStacker.Push(filler);
}
catch(FullStack){
cout << endl << "Stack is full, name not pushed" << endl;
}
cout << endl << "Popped: ";
while(!PStacker.IsEmpty()){
filler = PStacker.Top();
PStacker.Pop();
filler.Print();
}
try{
PStacker.Pop();
}
catch(EmptyStack){
cout << endl << "Stack is empty, name not popped" << endl;
}
return 0;
}
The PointerStack class
#include "PointerStack.h"
PointerStack::PointerStack(){
top = NULL;
}
/*PointerStack::~PointerStack(){
Node* temp;
while(top != NULL){
temp = top;
top = top->next;
delete temp;
}
}*/
void PointerStack::Push(NameItem item){
if(IsFull())
throw FullStack();
else{
Node* location;
location = new Node;
location->data = item;
location->next = top;
top = location;
}
}
void PointerStack::Pop(){
if(IsEmpty())
throw EmptyStack();
else{
Node* temp;
temp = top;
top = top->next;
delete temp;
}
}
NameItem PointerStack::Top(){
if(IsEmpty())
throw EmptyStack();
else{
return top->data;
}
}
bool PointerStack::IsEmpty() const{
return (top == NULL);
}
bool PointerStack::IsFull() const{
Node* location;
try{
location = new Node;
delete location;
return false;
}
catch(std::bad_alloc& exception){
return true;
}
}
And the NameItem class
#include <fstream>
#include "NameItem.h"
NameItem::NameItem()
{
name = " ";
}
RelationType NameItem::ComparedTo(NameItem otherItem) const
{
if (name < otherItem.name)
return LESS;
else if (name > otherItem.name)
return GREATER;
else
return EQUAL;
}
void NameItem::Init(string value)
{
name = value;
}
void NameItem::Print() const
{
cout << name << " ";
}
Final note, the main program has more code for testing the Stack class included in the program. I removed the code since it is not related to the error, and the program still crashes, but it crashes immediately with a windows error box rather than with console gibberish/beeps. Not sure if that is relevant or not…
The problem is twofold.
First, you are emptying the
PStackerobject inPrintPointerStack(), then trying to access the top element of that empty stack. This should throw anEmptyStack. The fact that this is not happening, indicates another problem as well (see below).Second, the fact that giberish is printed (sometimes) indicates that you are trying to access data through invalid objects/pointers. Indeed, because you are passing the parameter of
PrintPointerStack()via pass-by-value, the default copy-constructor is invoked that blindly copies the value of thetoppointer. Then you proceed to delete objects, but thetoppointer in the originalPStackeris not changed, thus now is invalid. Hence your problem.To fix, you either need to pass the parameter to
PrintPointerStack()by pointer/reference or provide a better suiting copy-constructor that does a deep copy (instead of the shallow copy provided by the default copy-constructor).