I'm new to this website and will try to contribute just as much as I ask. Also, please know I never ask a question without spending much time trying to figure it out myself.
As such, C++ Stacks are driving me f***ing crazy.
My Question: where do I place my variables/values in the Stack function block to actually use it. I understand Stacks are a LIFO data-structure, I've read countless examples of stacking plates on top of each other, etc.
Look at this code:
#include <iostream>
using namespace std;
const int MAX_SIZE = 100;
class StackOverFlowException
{
public:
StackOverFlowException()
{
cout << "Stack overflow" << endl;
}
};
class StackUnderFlowException
{
public:
StackUnderFlowException()
{
cout << "Stack underflow" << endl;
}
};
class ArrayStack
{
private:
int data[MAX_SIZE];
int top;
public:
ArrayStack()
{
top = -1;
}
void Push(int element)
{
if ( top >= MAX_SIZE )
{
throw new StackOverFlowException();
}
data[++top] = element;
}
int Pop()
{
if ( top == -1 )
{
throw new StackUnderFlowException();
}
return data[top--];
}
int Top()
{
return data[top];
}
int Size()
{
return top + 1;
}
bool isEmpty()
{
return ( top == -1 ) ? true : false;
}
};
[etc....]
It's basic cookie-cutter....let's say I'm trying to adapt it to express a system where the last food orders placed in, are kicked out first; variables are 'food', 'orders', and whatever else.
Where in the world am I integrating those variables into that stack code above!?!??!
Please help so confused i'm about to indiscriminately punch something
A stack implementation could use templates so that you could put whatever you want in the stack (within reason).
For example, have a class that encapsulates all the data related to orders (this one is just an example):
class FoodOrder
{
int orderNumber;
time_t orderTime;
// add more variables here
}
Then, your stack could look like this:
template<typename T> class Stack
{
T data[MAX_SIZE];
int top;
void Push(T item);
T Pop(void);
// add methods
}
Then, you could have a Stack of whatever items you want:
Stack<int> stackOfInts;
Stack<std::string> stackOfStrings;
Stack<FoodOrder> stackOfOrders;
Use the existing std::stack and wrap it if you want the exceptions, for example like this (note you could easily templatize it):
class protectedstack
{
private:
std::stack<int> stack;
const int myarbitraryupperlimit = 100;
public:
void pop()
{
if(stack.empty())
{
throw new StackUnderFlowException();
}
stack.pop();
}
void push(const int& value)
{
if(stack.size()>=myarbitraryupperlimit)
{
throw new StackOverFlowException();
}
stack.push(value);
}
// Similar for top/empty/constructors/...
};
The type of data, as well as that of what Top & Pop return, and what Push takes as an argument, is what is contained in the stack; that's what you'd replace w/ the type of whatever you want to make this a stack of.
This is a stack:
Think of it this way: the only way to add a book without moving the others is to place it on top : this is what Push does. So by calling Push(Book1), you'd be placing Book1 on top of the pile.
Similarly, the only way to take away a book without moving the others is to take the one on top : this is what Pop does. So by calling Pop(), you'd be getting (and removing from the stack) whichever book is on top of the stack, which in the image is the green book.
Am I missing something or was this your question?
It's all in the top variable. This variable dictates which object is the current top. When you pop(), then the top variable is reduced- meaning that the top is now one below where it was. When you push(), it's incremented- the top is now one above where it was. This variable is what accounts for the LIFO functionality of the stack.
You can, of course, template the class to make it work with a FoodOrder or whatever.
I don't see why the confusion. The data would go in, duh!, the "data" variable.
So, you either use Templates, to make the data buffer able to hold anything, or you change the type of the data to what you specifically need.
If for example you have a FoodOrder class, you can do it like this (my C++ is rusty, but this is basically the gist of it):
FoodOrder *data[MAX_SIZE];
You would have to change the push/pop parameters to accept a FoodOrder pointer/reference accordingly, and you're set.
P.S. About using std::stack --this might be a better solution, but doesn't answer his specific question.
P.S 2 Poster writes: "I'm new to this website and will try to contribute just as much as I ask.". Really? So why hasn't he even picked an answer yet? Does this smell more like a homework assignment?
Related
In this situation, I want to delete book, but I try declare this code, its not working.
class Library {
private:
Book **books;
int counter;
public:
Library() {
books = NULL;
counter = 0;
}
void Add(INPUT &tmp) {
books = new Book*[counter];
++counter;
}
void Delete() {
--counter;
delete[] books[counter];
books[counter] = NULL;
}
int getCounter() {
return this->counter;
}
~Library() {
delete[] books;
}
};
Before you get deleting to work, you need to get adding right.
In addition to what Jeffrey said, your Add function probably doesn't work correctly due to an "out by one" error. In the first call you will have books = new Book*[0];. Allocating a zero sized array is legal (see here) but you will not be able to store anything in it.
If you can use a std::vector it will make your code much simpler and less error prone.
class Library {
private:
std::vector<Book> books;
// no need for counter, std::vector has size()
public:
// no need for a constructor, the default constructor
// will correctly construct 'books'
void Add(INPUT &tmp) {
// not sure how you convert 'INPUT' to 'Book'
books.push_back(tmp);
// this handles all of the memory management for you
}
void Delete() {
// you need to ensure that books is not empty
books.pop_back();
}
int getCounter() {
return books.size();
}
// no need for a destructor, the default one will
// do everything
};
If you need two dimensions, then the code is similar but will use a vector of vector.
Book **books;
is a pointer to a pointer to a book. It is the old style way of having a list of books (as pointers) or a list of list of books.
Library() {
books = NULL;
counter = 0;
}
This will create an empty library. No books.
void Add(INPUT &tmp) {
books = new Book*[counter];
++counter;
}
First thing to notice is that you are not using the tmp book. So you probably won't succeed in storing it anywhere, without using it.
Second thing is that books = new Book*[counter]; allocates a library of books. Space for storing some books. You probably should do that in the constructor. If you do it there, every time you try to add a book, you'll lose all the others, and you'll also leak memory.
There's two possibilities here. You have an old-timer C++ professor, and you'll need to learn about pointers and pointers to pointers, and new, delete. Or you could learn about std::vectors and smart-pointers. This would be a better idea, but I can't tell you how well it will be received in your class.
Also, please state what INPUT is defined as.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
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.
Improve this question
Well I am doing an assignment but not sure what my problem is
this is my assignment
Instructions You have two parts to this assignment. The parts are related, but different in their implementation. To better understand the assignment itself, it may be helpful to go back through the book, slides, notes, etc. and do implementations of the regular array-based and linked list-based Stack, along with the Stack ADT.
Part I
One widespread use of stacks is to provide the undo operation, familiar to us from many different applications. While support for undo can be implemented with an unbounded stack (one that keeps growing and growing as long as memory permits), many applications provide only limited support for such an undo history. In other words, the stack is fixed-capacity.
When such a stack is full, and push is invoked, rather than throwing an exception, a more typical approach is to accept the pushed element at the top, while removing the oldest element from the bottom of the stack to make room. This is known as “leaking.” Note that this does not mean that the ADT exposes a method to allow removal from the bottom directly. This is only performed when the stack becomes full.
For this part, you are to give an implementation of such a LeakyStack abstraction, using some array-based implementation.
Note that you must create a Leaky Stack interface, and then use the C++ : operator to implement that interface (using public inheritance) with your LeakyArrayStack implementation. See the Interface specified near the end of the assignment instructions.
Part II Repeat Part I, but use a singly linked list instead of an array for the actual data storage, and allow for a maximum capacity specified as a parameter to the constructor.
NOTES: • Both the array-based and linked-list based Leaky Stacks should use the same LeakyStackInterface, specified below. Remember – this is a LeakyStack ADT. It specifies what the LeakyStack does, not how. So, the interface should not be different in order to provide an implementation. • Use public inheritance in both Parts • You should write a SinglyLinkedList class first, before trying to do part II o Then, use containment (aggregation or composition, a has-a relationship) to implement the part II
I GOT TO USE THE INTERFACE IN THE PICTURE
this is my code
#include <iostream>
#ifndef LEAKYStacksINTERFACE
#define LEAKYStacksINTERFACE
#define cap 10
using namespace std;
template<typename ItemType>
class LeakyStacksInterface
{ public:
//returns whether Stacks is empty or not
virtual bool isEmpty() const = 0;
//adds a new entry to the top of the Stacks
//if the Stacks is full, the bottom item is removed
//or "leaked" first, and then the new item is set to the top
//---> If the Stacks was full when the push was attempted, return false
//---> If the Stacks was not full when the push was attempted, return true
virtual bool push(const ItemType& newEntry) = 0;
//remove the top item
//if the Stacks is empty, return false to indicate failure
virtual bool pop() = 0;
//return a copy of the top of the Stacks
virtual ItemType peek() const = 0;
//destroys the Stacks and frees up memory
//that was allocated
// virtual ~StacksInterface() {}
};
template<typename ItemType>
struct node
{
int data;
struct node *next;
};
template<typename ItemType>
class Stacks : public LeakyStacksInterface<ItemType>
{
struct node<ItemType> *top;
public:
int size;
ItemType *myArray;
Stacks()
{
top=NULL;
size = 0;
myArray = new ItemType[cap];
}
~Stacks() {
size = 0;
}
public:
// pure virtual function providing interface framework.
bool isEmpty() const {
return(size == 0);
}
bool push(const ItemType& newEntry) {
if(size == cap) {
for(int i = 0; i < size-1; i++) {
myArray[i] = myArray[i+1];
}
myArray[size-1] = newEntry;
return false;
}
}
ItemType peek() const {
return myArray[size-1];
}
void display()
{
cout<<"Stacks: [ ";
for(int i=size-1; i>=0; i--)
{
cout<<myArray[i]<<" ";
}
cout<<" ] "<<endl;
}
};
int main()
{
Stacks s;
int choice;
while(1)
{
cout<<"n-----------------------------------------------------------";
cout<<"nttSTACK USING LINKED LISTnn";
cout<<"1:PUSHn2:POPn3:DISPLAY STACKn4:EXIT";
cout<<"nEnter your choice(1-4): ";
cin>>choice;
switch(choice)
{
case 1:
s.push();
break;
case 2:
s.pop();
break;
case 3:
s.show();
break;
case 4:
return 0;
break;
default:
cout<<"Please enter correct choice(1-4)!!";
break;
}
}
return 0;
}
#endif
HERE ARE MY ERRORS :
ERROR:missing template arguments before 's'
ERROR:expected ';' before 's'
ERROR:'s' was not delcared in this scope
please help!
Thank You!
INTERFACE PICTURE
Stacks is a class template, so to use it you must provide a template argument, like
Stacks<int> s;
Example:
bool isHeapPtr(void* ptr)
{
//...
}
int iStack = 35;
int *ptrStack = &iStack;
bool isHeapPointer1 = isHeapPtr(ptrStack); // Should be false
bool isHeapPointer2 = isHeapPtr(new int(5)); // Should be true
/* I know... it is a memory leak */
Why, I want to know this:
If I have in a class a member-pointer and I don't know if the pointing object is new-allocated. Then I should use such a utility to know if I have to delete the pointer.
But:
My design isn't made yet. So, I will program it that way I always have to delete it. I'm going to avoid rubbish programming
There is no way of doing this - and if you need to do it, there is something wrong with your design. There is a discussion of why you can't do this in More Effective C++.
In the general case, you're out of luck, I'm afraid - since pointers can have any value, there's no way to tell them apart. If you had knowledge of your stack start address and size (from your TCB in an embedded operating system, for example), you might be able to do it. Something like:
stackBase = myTCB->stackBase;
stackSize = myTCB->stackSize;
if ((ptrStack < stackBase) && (ptrStack > (stackBase - stackSize)))
isStackPointer1 = TRUE;
The only "good" solution I can think of is to overload operator new for that class and track it. Something like this (brain compiled code):
class T {
public:
void *operator new(size_t n) {
void *p = ::operator new(n);
heap_track().insert(p);
return p;
}
void operator delete(void* p) {
heap_track().erase(p);
::operator delete(p);
}
private:
// a function to avoid static initialization order fiasco
static std::set<void*>& heap_track() {
static std::set<void*> s_;
return s_;
}
public:
static bool is_heap(void *p) {
return heap_track().find(p) != heap_track().end();
}
};
Then you can do stuff like this:
T *x = new X;
if(T::is_heap(x)) {
delete x;
}
However, I would advise against a design which requires you to be able to ask if something was allocated on the heap.
Well, get out your assembler book, and compare your pointer's address to the stack-pointer:
int64_t x = 0;
asm("movq %%rsp, %0;" : "=r" (x) );
if ( myPtr < x ) {
...in heap...
}
Now x would contain the address to which you'll have to compare your pointer to. Note that it will not work for memory allocated in another thread, since it will have its own stack.
here it is, works for MSVC:
#define isheap(x, res) { \
void* vesp, *vebp; \
_asm {mov vesp, esp}; \
_asm {mov vebp, ebp}; \
res = !(x < vebp && x >= vesp); }
int si;
void func()
{
int i;
bool b1;
bool b2;
isheap(&i, b1);
isheap(&si, b2);
return;
}
it is a bit ugly, but works. Works only for local variables. If you pass stack pointer from calling function this macro will return true (means it is heap)
In mainstream operating systems, the stack grows from the top while the heap grows from the bottom. So you might heuristically check whether the address is beyond a large value, for some definition of "large." For example, the following works on my 64-bit Linux system:
#include <iostream>
bool isHeapPtr(const void* ptr) {
return reinterpret_cast<unsigned long long int>(ptr) < 0xffffffffull;
}
int main() {
int iStack = 35;
int *ptrStack = &iStack;
std::cout << isHeapPtr(ptrStack) << std::endl;
std::cout << isHeapPtr(new int(5)) << std::endl;
}
Note that is a crude heuristic that might be interesting to play with, but is not appropriate for production code.
First, why do you need to know this? What real problem are you trying to solve?
The only way I'm aware of to make this sort of determination would be to overload global operator new and operator delete. Then you can ask your memory manager if a pointer belongs to it (the heap) or not (stack or global data).
Even if you could determine whether a pointer was on one particular heap, or one particular stack, there can be multiple heaps and multiple stacks for one application.
Based on the reason for asking, it is extremely important for each container to have a strict policy on whether it "owns" pointers that it holds or not. After all, even if those pointers point to heap-allocated memory, some other piece of code might also have a copy of the same pointer. Each pointer should have one "owner" at a time, though ownership can be transferred. The owner is responsible for destructing.
On rare occasions, it is useful for a container to keep track of both owned and non-owned pointers - either using flags, or by storing them separately. Most of the time, though, it's simpler just to set a clear policy for any object that can hold pointers. For example, most smart pointers always own their container real pointers.
Of course smart pointers are significant here - if you want an ownership-tracking pointer, I'm sure you can find or write a smart pointer type to abstract that hassle away.
Despite loud claims to the contrary, it is clearly possible to do what you want, in a platform-dependent way. However just because something is possible, that does not automatically make it a good idea. A simple rule of stack==no delete, otherwise==delete is unlikely to work well.
A more common way is to say that if I allocated a buffer, then I have to delete it, If the program passes me a buffer, it is not my responsibility to delete it.
e.g.
class CSomething
{
public:
CSomething()
: m_pBuffer(new char[128])
, m_bDeleteBuffer(true)
{
}
CSomething(const char *pBuffer)
: m_pBuffer(pBuffer)
, m_bDeleteBuffer(false)
{
}
~CSomething()
{
if (m_bDeleteBuffer)
delete [] m_pBuffer;
}
private:
const char *m_pBuffer;
bool m_bDeleteBuffer;
};
You're trying to do it the hard way. Clarify your design so it's clear who "owns" data and let that code deal with its lifetime.
here is universal way to do it in windows using TIP:
bool isStack(void* x)
{
void* btn, *top;
_asm {
mov eax, FS:[0x08]
mov btn, eax
mov eax, FS:[0x04]
mov top, eax
}
return x < top && x > btn;
}
void func()
{
int i;
bool b1;
bool b2;
b1 = isStack(&i);
b2 = isStack(&si);
return;
}
The only way I know of doing this semi-reliably is if you can overload operator new for the type for which you need to do this. Unfortunately there are some major pitfalls there and I can't remember what they are.
I do know that one pitfall is that something can be on the heap without having been allocated directly. For example:
class A {
int data;
};
class B {
public:
A *giveMeAnA() { return &anA; }
int data;
A anA;
};
void foo()
{
B *b = new B;
A *a = b->giveMeAnA();
}
In the above code a in foo ends up with a pointer to an object on the heap that was not allocated with new. If your question is really "How do I know if I can call delete on this pointer." overloading operator new to do something tricky might help you answer that question. I still think that if you have to ask that question you've done something very wrong.
How could you not know if something is heap-allocated or not? You should design the software to have a single point of allocation.
Unless you're doing some truly exotic stuff in an embedded device or working deep in a custom kernel, I just don't see the need for it.
Look at this code (no error checking, for the sake of example):
class A
{
int *mysweetptr;
A()
{
mysweetptr = 0; //always 0 when unalloc'd
}
void doit()
{
if( ! mysweetptr)
{
mysweetptr = new int; //now has non-null value
}
}
void undoit()
{
if(mysweetptr)
{
delete mysweetptr;
mysweetptr = 0; //notice that we reset it to 0.
}
}
bool doihaveit()
{
if(mysweetptr)
return true;
else
return false;
}
~A()
{
undoit();
}
};
In particular, notice that I am using the null value to determine whether the pointer has been allocated or not, or if I need to delete it or not.
Your design should not rely on determining this information (as others have pointed out, it's not really possible). Instead, your class should explicitly define the ownership of pointers that it takes in its constructor or methods. If your class takes ownership of those pointers, then it is incorrect behavior to pass in a pointer to the stack or global, and you should delete it with the knowledge that incorrect client code may crash. If your class does not take ownership, it should not be deleting the pointer.
I'm trying to implement the Ford Fulkerson Algorithm in C++.
However, I'm having trouble with my find_edge function. When I call this function in my_alg, it chooses the correct edge and then the flow is incremented in my_alg. It chooses the right edge and increment its flow (flow), but when I call the find_edge function again, the flow is not incremented as it should be.
This results in an endless loop of my algorithm. Probably I do something wrong with the pointers. You can see my code below.
//An object of this class represents an edge in the graph.
class Edge
{
private:
//Node *prev;
public:
int flow;
Edge(Node *firstNode, Node *secNode, unsigned inCost) {
orgNode = firstNode;
dstNode = secNode;
bridge_capacity = inCost;
}
Edge() {
flow=0;
}
};
//An object of this class holds a vertex of the graph
class Node
{
public:
Node *prev;
vector<Edge>& getAdjNodeList() {
return adjNodeList;
}
};
Edge *find_edge(Graph *g,Node *from,Node *to) {
vector<Edge> b=from->getAdjNodeList();
for(int i=0;i<b.size();i++) {
if(b[i].getDstNode()==to)
return (&b[i]);
}
return NULL;
}
int my_alg(Graph *as,Node *source,Node *sink){
Edge *find_edge();
int max_flow=0;
while(bfs(as,source,sink)) {
Node *b=as->nodeList[num_isl];
int inc=100000000;
while(b->prev!=NULL) {
Edge *bok=find_edge(as,b->prev,b);
inc=min(inc,bok->get_bridge_capacity()-bok->flow);
b=b->prev;
}
b=as->nodeList[num_isl];
while(b->prev!=NULL){
Edge *bok = find_edge(as,b->prev,b);
bok->flow += inc; // This is the place the flow is incremented
bout << bok->flow; // Here, everything is alright.
bok = find_edge(as,b->prev,b);
cout << bok->flow; // However, this is is not the correct result.
}
max_flow+=inc;
}
return max_flow;
}
I had a more thorough look at your code. To help you track your problems down yourself in the future, I will show you a sample process of finding the error.
If you really can not find the problem by looking at the code, you may want to strip down everything that obfuscates your view on the problem. The reduced code could look like this:
class Edge {
public:
int flow;
};
class Node {
private:
vector<Edge> adjNodeList; // list of outgoing edges for this vertex
public:
vector<Edge> & getAdjNodeList() {
return adjNodeList;
}
void addAdjNode(Node* newAdj) {
adjNodeList.push_back(Edge(newAdj));
}
};
int main() {
Node *node1 = new Node();
Node *node2 = new Node();
node1->addAdjNode(node2);
vector<Edge> t = node1->getAdjNodeList();
vector<Edge> f = node1->getAdjNodeList();
t[0].flow = 11;
cout << t[0] << endl;
cout << f[0] << endl;
}
If you would run this code, you would notice that t[0] and f[0] are not the same. As I just copied the crucial elements of your code, the reason should still be the same.
What is happening here? When calling
vector<Edge> t = node1->getAdjNodeList();
the adjacency list is returned by reference, which should leave you with a reference to the original list - you should be able to change it's elements, shouldn't you? However, when assigning this reference to the newly allocated vector t, the implicit copy constructor is called, thus t will contain a copy (!) of your vector while you wanted to save a reference.
To get around this problem, you could just have done the following:
vector<Edge> & t = node1->getAdjNodeList();
which saves the reference and does not create a new object.
I can only assume why the pointers happened to be identical between calls to the function: The object probably was copied to the same place every time. Furthermore, note that you increased the value of an object that did not exist anymore - the copy was deleted with the end of the find_edge-call.
It took some time to give an answer to your question as you did not track the problem down yourself. If you had given the example above, I bet your solution would have been there within a matter of minutes. You are encouraged to raise your problems here at stack overflow - however, most members will not be willing to work through a lot of code to identify the problem themselves. That means, high quality answers usually require questions that directly come to the point. (The last paragraph was intended to help you in the future, however, it could be reduced without altering the question).
Apart from that, I would strongly encourage you not to use your objects the way you do. By passing everything as references and making all changes outside the object, you essentially bypass the encapsulation that makes object orientated programming that powerful. For example, it would be much wiser (and would not have given you your problem) if you just had added another function increaseFlow(Edge* to, int increment) to your Node and had done everything within the object.
Hope I could help.
I'm fairly new to C++ and new to pointers as well. I'm currently working on a stack and was trying to reallocate the memory for the stack as the size of the stack reaches the top however, I'm running into issues. I've already done a lot of research both on Google and stack overflow and have found some information helpful but since I'm so new to stacks and C++ I'm still having issues. I was hoping some bright and intelligent people could at least point me in the right direction.
now... Here's my code.
#include <iostream>
#define STACKMAX 20
using namespace std;
template <class T> class StackTemplated {
private:
int top;
T values[STACKMAX];
public:
StackTemplated();
void push(T i);
T pop(void);
bool empty(void);
};
template <class T> StackTemplated<T>::StackTemplated() {
top = -1;
}
template <class T>void StackTemplated<T>::push(T i) {
if (top == STACKMAX - 1) {
// reallocate top of stack. (this is the area I'm having issues)
char * string1;
string1 = (char *)calloc(STACKMAX, sizeof(char));
if (top == STACKMAX - 1) {
cout << "The stack didn't re-allocate.";
exit(1);
}
} else {
top++;
values[top] = i;
}
}
template <class T> T StackTemplated<T>::pop(void) {
if (top < 0) {
printf("%", "Stack underflow!");
exit(1);
} else {
return values[top--];
}
}
template <class T> bool StackTemplated<T>::empty() {
return (top == -1);
}
Here's a list of a few things I noticed:
STACKMAX is a constant. If you're expanding the stack, how will you keep track of how big it currently is?
The values member is a fixed-size array. You won't be able to change the size of it dynamically without changing how this is declared and allocated.
calloc() allocates a new chunk of memory with the number of bytes you specify. You'll need to somehow copy the existing stack into the new memory block, and free the previous one.
You're allocating only STACKMAX bytes in the call to calloc(). You'll probably want to scale this by sizeof T, in case T is not a char.
There will be a lot of details for you to fix up once you address these major points. Good luck.
The problem is that you don't want to reallocate the top of the stack. Rather, you want to allocate a new array of values which is large enough to hold the new values. Also, since you need to reallocate the array, values should be a pointer.
But how about we forget all this. If we're working in c++, let's use what c++ offers us to make our lives easier. After that's done, then try open things up, if you really feel the need.
One of the things I'm referring to is your use of calloc. Using calloc is a bad idea, particularly when using templates. The problem is that since calloc has no type information, it won't do something as basic as calling a constructor. Constructors are very important in OOP, since they guarantee that an object's invariance when it is created. Instead, use the new[] keyword, like
values = new T[STACKMAX];
This allocates an array of T of STACKMAX length. Of course, as Greg points out, you should reconsider the use of STACKMAX, and use a variable instead. Also, values shouldn't be a static array, but should instead have type T*.
Another thing I was referring to is the fact that you are really trying to implement an array which grows dynamically as needed. In c++, we call such a structure a vector. If you use a vector, your entire code reduces to
#include<iostream>
#include<vector>
using namespace std;
template<class T> class StackTemplated {
private:
std::vector<T> vec;
public:
StackTemplated() { } // the constructor is trivial; in fact, you can leave it out if you want
void push(T i);
T pop(void);
bool empty(void);
};
template<class T>
void StackTemplated<T>::push(T i) {
vec.push_back(i);
}
template<class T>
T StackTemplate<T>::pop(void) {
T top = vec.back();
vec.pop_back();
return top;
}
template<class T>
bool StackTemplate<T>::isEmpty(void) {
return vec.size() == 0;
}
That's all. It's a lot less hairy if you can use an existing data structure to implement the new data structure.
Once you get really comfortable with how a vector works (and there's plenty of explanations / documentation on the web), then try implementing the functionality yourself. Bottom line is, implementing a data structure is a lot easier if you know exactly how it's supposed to behave.
I would declare your values like
T* vaules;
Then use new to create it not calloc. You will need to keep track of the top of the stack and size of it. As Greg says when you grow the stack make sure and copy data over and clean up the old one.