Thread: Need Help with Stack

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    25

    Need Help with Stack

    Hi everybody,
    My Stack class here is used to performance a simply task of stack. I modified this class from another that has 2 parts, one is a structure making up the frame of the list's nodes , and the class is just responsible for building up the list. It's much clearer and easier to understand, but I try to combine them as one class as shown below.
    Take a look at the destructor, each time one dynamic object created by push() function, right after that, it destroys that object once the push() function end. If I remove the destructor, this class work well, since pop() function is responsible for discarding the top node of the list. However, I want to implement the destructor for the class, is there the best way to deal with this ? Thanks in advance.
    Here is my code :

    Code:
    #include <iostream>
    #include "stack.h"
    using namespace std;
    
    //the class definition
    
    class Stack
    {
    	public:
            Stack( );
            //Initializes the object to an empty stack.
    
            Stack(const Stack& a_stack);
            //Copy constructor.
    
            ~Stack( );
            //Destroys the stack and returns all the memory to the freestore.
    
            void push(char the_symbol);
        
    
            char pop( );
            
    
            bool empty( ) const;
            //Returns true if the stack is empty. Returns false otherwise.
        private:
            char data;
    		Stack *link;
    		Stack *top;
    
    };
    
    #endif //STACK_H
    
        //Uses cstddef:
    Stack::Stack( ) : data(NULL), link(NULL),top(NULL)
    {
            //empty.
    }
    
        
    Stack::Stack(const Stack& a_stack)
    {
    	if (a_stack.top == NULL)
    		top = NULL;
    	else
           {
    	    Stack *temp = a_stack.top;//temp moves
                    //through the nodes from top to bottom of 
                    //a_stack.
                Stack *end;//Points to end of the new stack.
    
    	    end = new Stack;
                end->data = temp->data;
                top = end;
                //First node created and filled with data.
                //New nodes are now added AFTER this first node.
    
                temp = temp->link;
                while (temp != NULL)
               {
    	       end->link = new Stack;
                   end = end->link;
                   end->data = temp->data;
                   temp = temp->link;
    	   }
    
                end->link = NULL;
    	}
    }
    
    Stack::~Stack( )
    {
    		//destructor will be called when we push one node into the list
    		//so the node just borned will be destroyed immediately.
    	cout<<"check "<<pop()<<"-";
    // I NEED HELP HERE ... ************************
    
    }
    
        //Uses cstddef:
    bool Stack::empty( ) const
    {
    	return (top == NULL);
    }
    
        //Uses cstddef:
    void Stack::push(char the_symbol)
    {
        Stack *temp_ptr;
        temp_ptr = new Stack;
    
        temp_ptr->data = the_symbol;
    
        temp_ptr->link = top;
        top = temp_ptr;
    		//the destructor will be called when the dynamic variable pointed to by temp_ptr
    		//goes out of scope.
    }
    
        //Uses iostream:
    char Stack::pop( )
    {
    	if (empty( ))
        {
    	cout << "Error: popping an empty stack.\n";
            exit(1);
         }
    
         char result = top->data;
    
         Stack *temp_ptr;
         temp_ptr = top;
         top = top->link;
    
         delete temp_ptr;
    
         return result;
    }
    
    
    // program body
    
    int main( )
    {
        Stack s;
        char next, ans;
    
        do
        {
            cout << "Enter a word: ";
            cin.get(next);
            while (next != '\n')
            {
                s.push(next);
                cin.get(next);
            }
    
            cout << "Written backward that is: ";
            while ( ! s.empty( ) )
                cout << s.pop( );
            cout << endl;
    
            cout << "Again?(y/n): ";
            cin >> ans;
            cin.ignore(10000, '\n');
        }while (ans != 'n' && ans != 'N');
    
        return 0;
    }
    Last edited by trongsi; 05-22-2006 at 09:40 PM.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    The best way would be to use an std::vector<> instead of simulating it. Without offense. You will not be able to match its efficiency.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    25
    Quote Originally Posted by Desolation
    The best way would be to use an std::vector<> instead of simulating it. Without offense. You will not be able to match its efficiency.
    Thank you, but I've been learning C++, so I want to understand and practice the part I've just learned.

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    903
    Learning how to use the STL containers is one of the best things you can do. No matter what kind of program I make I always need STL containers.

  5. #5
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Well then why doesn't he use the Stack provided by the STL.
    Nothing wrong with learning how stuff works and then gracefully moving on to the STL.
    Woop?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The best way would be to use an std::vector<> instead of simulating it.
    Might as well use std::stack, though that may be implemented with a std::vector.

    Anyway, I suggest that you take a look at the interface provided by std::stack. Notice that pop() does not return the value popped. Instead top() is used to get the top of the stack.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    the easiest way to implement a stack is with an array and an integer (or pointer) for indexing the top of the stack.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    25
    Thank you all for your advisings.
    But my question was can I have a correct destructor for this class ? I mean, assume if we just let the user enter the nodes for stack without using them (so they're still stored in memory), do we have any way to release that memory automatically (by using destructor). Using the destructor in this situation, we never have a node in a list because the new-born node (creating by push() function) will be destroyed right after the function call ends.
    The text books recommend programmers having the Big Three (copy constructor, destructor, and overloading = operator) each time we build a class that uses pointers and new operator. So how to follow this convention in this situation ?

  9. #9
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Since you are basing your Stack class on a list, then each time you push a node onto the Stack you need to declare memory for it and every time you pop a node off the Stack you should delete the memory. You do all that. A Stack object can exist without any nodes associated with it. You can empty any given stack multiple times without actually destroying it. The destructor for the Stack object will only be called when the Stack object itself, not the nodes associated with the Stack object, goes out of scope.

    NB--memory declared by new doesn't go out of scope until you delete it, so the when push() ends the memory for the new link isn't automatically released and the new link object still exists.
    Last edited by elad; 05-23-2006 at 09:58 AM.
    You're only born perfect.

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    25
    Quote Originally Posted by elad
    Since you are basing your Stack class on a list, then each time you push a node onto the Stack you need to declare memory for it and every time you pop a node off the Stack you should delete the memory. You do all that. A Stack object can exist without any nodes associated with it. You can empty any given stack multiple times without actually destroying it. The destructor for the Stack object will only be called when the Stack object itself, not the nodes associated with the Stack object, goes out of scope.

    NB--memory declared by new doesn't go out of scope until you delete it, so the when push() ends the memory for the new link isn't automatically released and the new link object still exists.
    Yes, that was what I based on that to create this class. I do understand you. The one I based on was:

    - A structure (or even a class) that defines the nodes' framework
    - A Stack class that do the task of pushing, popping nodes, including copy constructor & destructor.

    Code:
    // framework for a node
    
    struct Nodeframe 
    {
      char data;
      Nodeframe *link;
    }
    
    
    class Stack
    {
      public:
         /* member function such as constructors, destructor, push(), pop() */
      
      private:
        Nodeframe *top;
    }
    
    /* assume that all member function are modified appropriately
        and the destructor will be defined: 
    */
    
    Stack:~Stack()
    {
        char tempdata; //we don't need to get the return value of pop(), just use to call the function    
        while (!=empty())
        tempdata = pop(); //call pop() to destroy each node
    }
    
    /* Is this one much clearer than the one I posted before ? */

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stack and pointer problem
    By ramaadhitia in forum C Programming
    Replies: 2
    Last Post: 09-11-2006, 11:41 PM
  2. infix evaluation using stack
    By lewissi in forum C++ Programming
    Replies: 0
    Last Post: 11-03-2005, 02:56 AM
  3. Question about a stack using array of pointers
    By Ricochet in forum C++ Programming
    Replies: 6
    Last Post: 11-17-2003, 10:12 PM
  4. error trying to compile stack program
    By KristTlove in forum C++ Programming
    Replies: 2
    Last Post: 11-03-2003, 06:27 PM
  5. Stack Program Here
    By Troll_King in forum C Programming
    Replies: 7
    Last Post: 10-15-2001, 05:36 PM