When I test my stack with an int when I do pop all it seems to return is the address of the thing that I want and not the value, which makes sense since I return something by reference.. but I just cant seem to figure out what to do to get around this.

What I need my .pop function to do is return a node, which is a pointer, and be able to copy that pointer to another pointer.

such as:

//TreeNode *child = myStack.pop();

that is what I need my code to do, but it is not working, can you all help?

template <typename T>
class Stack{

    private:

        std::vector<T> elems;     // elements

    public:

        void push(T const&);      // push element
        T* pop();               // pop element
        T top() const;            // return top element

        bool empty() const        // return whether the stack is empty
        {
            return elems.empty();
        }
};

template <typename T>
void Stack<T>::push(T const& elem){

    elems.push_back(elem);    // append copy of passed elem
}

template<typename T>
T* Stack<T>::pop(){


    if (elems.empty()){

        throw std::out_of_range("Stack<>::pop(): empty stack");
    }

    T value = elems.back();
   
    elems.pop_back();

    return &value;
}

template <typename T>
T Stack<T>::top() const{

    if (elems.empty()){

        throw std::out_of_range("Stack<>::top(): empty stack");
    }

    return elems.back();      // return copy of last element
}

this is what I have in my general tree class right now, to show you how I am implementing it

#include <iostream>
#include <fstream>
#include "Stack.h"

using namespace std;
class Tree{

private:

//inner node class
class TreeNode{

public:

//name of node
char name;
//number of children
int children;
//left most child
TreeNode *leftChild;
//right sibling
TreeNode *rightSibling;
//treenode constructor
TreeNode(char nodeName, int numChildren){

this->name = nodeName;
this->children = numChildren;
this->leftChild = NULL;
this->rightSibling = NULL;
}
};

//top of tree(stack form)
TreeNode *top;

public:

Tree::Tree(){

this->top = makeTree();
}

//tree creation
TreeNode* makeTree(){

//input file stream
ifstream fin;
//opens the file
fin.open("prog1.txt");
// Verifies file is opened correctly
if(!fin){
cout << "OOPS" << endl;
exit(1);
}

char name;
int count;

Stack<TreeNode> myStack;
do{

fin >> name >> count;

TreeNode *newNode = new TreeNode(name, count);
cout << newNode->name << newNode->children << endl;
cout << "here 1" << endl;

for(int kid = 0; kid < count; kid++){

//TreeNode *child = myStack.pop();
//cout << "here2" << endl;
//child->rightSibling = newNode->leftChild;
//newNode->leftChild = child;
//cout << child->name << child->children << endl;
}

myStack.push(*newNode);

cout << "also here" << endl;
TreeNode *myNode = myStack.pop();
cout << myNode->name << myNode->children << endl;

cout << "here3" << endl;

}while(!fin.eof());

return myStack.pop();

fin.close();
}

};

You're asking to return a pointer when you're really returning the address of an object that has fallen out of scope--

T value = elems.back(); //T value is a temporary object
 
elems.pop_back();
 
return &value; //the object in value fell out of scope before return

I'm honestly surprised you didn't get a compiler warning. Normally that happens when you attempt to return the value of a temporary object.

Try--

T *value = &elems.back(); //T *value is now a pointer that points to the address of 
                                       //the object 
elems.pop_back();
 
return value; //value should still exist

Thanks for your reply.

I changed my code as follows:

T* pop();

template<typename T>
T* Stack<T>::pop(){

    T *value = &elems.back(); 
    elems.pop_back();

    return value;
}

but when I do this in my main...

    Stack<int> myStack;

    myStack.push(2);
    myStack.push(3);

    cout << myStack.pop() << endl;
    cout << myStack.pop();

what is displayed is still the address not the actual value...

any ideas?

Edited 3 Years Ago by Dani: Formatting fixed

Thanks for your reply.

I changed my code as follows:

T* pop();

template<typename T>
T* Stack<T>::pop(){

T *value = &elems.back();
elems.pop_back();

return value;
}

but when I do this in my main...

Stack<int> myStack;

myStack.push(2);
myStack.push(3);

cout << myStack.pop() << endl;
cout << myStack.pop();

what is displayed is still the address not the actual value...

any ideas?

Notice that your pop method returns a pointer. Remember that when you make a call such as..

int a = 5; *iPtr = &a;

cout << iPtr << endl;

You're return the address the pointer is pointing to and not the value. What you want to do is dereference your method so when pop is called the actual value is displayed and not the address--

cout << *myStack.pop() << endl;
	cout << *myStack.pop();
This article has been dead for over six months. Start a new discussion instead.