So I'm trying to learn about Templates and the Fifo and Lifo stack stuff. I've been playing around with some code that deals with this, and I can get the int data to do what I want for testing but I can't for the life of me figure out how to get this to work with a string. The way I have the code keeps crashing on me, but doesn't give me any errors, so I thought I'd pop in here and see if anybody could tell me what I'm doing wrong. Here's my code:
-----------//my header//---------------------
#include <stdlib.h>
#include <iostream>
#include <string>
#ifndef STACK_H_
#define STACK_H_
template<class T>
class StackTest
{
private:
unsigned int maxSize;
T *stackData;
int top;
public:
StackTest(int size){
stackData = new T[size];//to hold the T type data items
top = -1;//no items on the stack
maxSize = size;//set maximum size that stack can hold
}
virtual ~StackTest(){}
int count(){
return top + 1;
}
bool isEmpty(){
return top == -1 ? true : false;
}
bool isFull(){
return top == maxSize - 1 ? true : false;
}
T* peek(){
if(!isEmpty())//check for empty
return &stackData[top - 1];
}
T* pop(){
if(!isEmpty()){
top -= 1;//decrease the top by 1 to indicate the delete
return &stackData[top];//return deleted item
}
return NULL;
}
void push(T* item){
stackData[top++] = *item;//insert to data array and increase the top by one
}
};
#endif /* STACK_H_ */
-----------//my main//---------------
#include <iostream>
#include <string>
#include "Pair.h"
using namespace std;
int main() {
int dataTest;
string strTest;
StackTest<int> intStack(10);
StackTest<string> stringStack(50);
//Insert data into the stack
dataTest = 3;
intStack.push(&dataTest);
dataTest = 4;
intStack.push(&dataTest);
dataTest = 5;
intStack.push(&dataTest);
dataTest = 6;
intStack.push(&dataTest);
strTest = "test";
stringStack.push(&strTest);
//Show the top item
cout << *intStack.peek() << endl;
cout << *stringStack.peek() << endl;
//Pull the top item out (twice)
intStack.pop();
intStack.pop();
//Show the new top item
cout << *intStack.peek() << endl;
return 0;
}
So if anyone feels like giving me some pointers I would really appreciate it, thanks.
There are a few issues with your implementation. One of the most subtle is in the
push()
member function:This is incrementing
top
and using the old value as an index intostackData
. Sincetop
is-1
when the stack is empty, your program is actually doing:Needless to say that the first assignment results in undefined behavior.
Another source of undefined behavior is the
peek()
member function, which does not return anything when the stack is empty:Per paragraph 6.6.3/2 of the C++11 Standard:
But that's not the only issue: the other problem is with the access of
stackData
:When
top
is not equal to or greater than one, this will also result in undefined behavior, since you would be taking the address of a (non-)object located at a negative address in the array.Also, I suggest to rewrite
isEmpty()
andisFull()
as follows:As a general advice, consider not using the value
-1
fortop
when the stack is empty. As Ben Voigt mentions in the comments, this is leading you to a lot of off-by-one errors.Also, as pointed out by DyP, your destructor is not freeing the memory allocated in the constructor, so your
StackTest
object is leaking memory. And after doing that, since we're at it, you may want to have a look at the so-called Rule of Three, that your program would be violating.