Thread: I wrote a piece of code, can't find where is the bug....

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    I wrote a piece of code, can't find where is the bug....

    Dear All:

    Here is the code I wrote.

    Code:
    #include <iostream>
    using namespace std;
    
    template <typename T>
    class Stack;
    
    template <typename T>
    class Node{
    private:
    	Node * next;
    	T* data;
    public:
    	friend class Stack<T>;
    	Node():next(0),data(0){}
    	Node( Node * head,  T * value):next(head),data(value){}
    	Node * GetNext(){ return next; }
    	void SetNext(const Node* newnext) {next = newnext;}
    	T* GetData() { return data; }
    	void SetData(const T* newdata) { data = newdata;}
    	virtual ~Node(){}
    };
    
    template <typename T>
    class Stack{
    public:
    	Stack():head(0){}
    	void Push( T* data);
    	T * Pop();
    	T * Top();
    	virtual ~Stack();
    private:
    	Node<T> * head;
    };
    
    template <typename T>
    void Stack<T>::Push( T* data){
    	head = new Node<T>(head,data);
    }
    
    template <typename T>
    T* Stack<T>::Pop(){
    	if (!head) return NULL;
    	Node<T> * oldhead = head;
    	T * result = head->GetData();
    	head = head->GetNext();
    	delete(oldhead);
    	return result;
    }
    
    template <typename T>
    T* Stack<T>::Top(){
    	if (!head) return NULL;
    	return (head->GetData());
    }
    
    template <typename T>
    Stack<T>::~Stack(){
    	while(head){ 
    		Node<T>* oldhead = head;
    		head = head->GetNext();
    		delete(oldhead);
    	}
    }
    
    
    
    int main(){
    	Stack<int>* test = new Stack<int>;
    	int x=1,y=2,z=3;
    	test->Push(&x);
    	test->Push(&y);
    	test->Push(&z);
    	cout<<*(test->Top())<<endl;
    	test->Pop();
    	cout<<*(test->Top())<<endl;
    	delete(test);
    
    	return 0;
    }
    This code implements a Stack.
    I tried to declare: (with const)
    Code:
    Node( const Node * head,  const T * value):next(head),data(value){}
    But it fails to complie... I am so confused....

    BTW, I would polish this Stack as safe as possible, any suggestions to improve the robustness?
    Last edited by meili100; 06-07-2007 at 05:04 PM.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    delete is only used for variables that have been dynamically allocated with new. You don't use it on ordinary variables. The destructor will be called anyway for the variable when it goes out of scope, when main (and thus your program) exits.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    Thank you, dwk.
    How about the question about 'const'?

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> But it fails to complie...
    What was the error message?

    >> I would polish this Stack as safe as possible, any suggestions to improve the robustness?
    Don't store pointers, store objects.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    Quote Originally Posted by Daved View Post
    >> But it fails to complie...
    What was the error message?
    error C2440: 'initializing' : cannot convert from 'const Node<T> *' to 'Node <T> *'

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    Quote Originally Posted by Daved View Post
    >>

    >> I would polish this Stack as safe as possible, any suggestions to improve the robustness?
    Don't store pointers, store objects.
    I don't think store objects is a good idea.
    For example, if the object is an instance of
    Code:
    class Ugly{
    char tmp[10];
    };
    
    
    Ugly node;
    Stack<Ugly> test;
    test.Push(node);
    Then the Node's copy constructor doesn't really "copy" the array but the pointer to the array.
    Unfortunately we can't design the Node<T> better becasue Node<T> knows nothing of the data structure of T.

  7. #7
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    No, but then a programmer does this:
    Code:
    class Nice
    {
      // includes various data types,
      // proper constructors, copy constructors, assignment, etc.
      // overall, a well built-class.
    };
    
    void somefunction(Stack<Nice> &test) {
    ...
      Nice node;
      // setting of node's members, etc.
      test.Push(&node);
    } // node goes out of scope, and test now contains an pointer to doom.
    This same design issue occurs with many of the std:: containers - and they store objects. You're right that the Node can't copy - this job is the classes, and if a class has data that requires a special copy constructor/assignment operator, then they should provide code for it, or use a Stack<Ugly *> to avoid it, and handle the pitfalls themselves.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    As Cactus_Hugger said, its the responsibility of the class to copy itself properly and the responsibility of the user of the stack to decide whether to store objects or pointers. By writing the stack to store object, you give the user a choice, since that "object" might be a pointer (e.g. Stack<Ugly *>).

    As for your compiler error, I guess the problem is that you have a pointer to a const node, and then you try to assign it to the member variable which is a pointer to a non-const node. I believe that since the const version promises to not change the object, but the non-const version doesn't, the compiler won't let you make the assignment. I don't think there is anything wrong with leaving it without the const, though.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can't find the BUG
    By keizer in forum C Programming
    Replies: 4
    Last Post: 08-10-2008, 05:03 AM
  2. Can't Find Bug in basic MP3 Sorter
    By trickeastcs in forum C++ Programming
    Replies: 12
    Last Post: 12-14-2007, 05:31 PM
  3. Help with a piece of code
    By Victor4015 in forum C++ Programming
    Replies: 1
    Last Post: 11-16-2005, 05:38 PM
  4. Help with a little piece of code
    By cdonlan in forum C Programming
    Replies: 5
    Last Post: 11-15-2004, 12:38 PM
  5. HELP! can't find that one error in my code
    By andyt2000 in forum C++ Programming
    Replies: 1
    Last Post: 09-21-2001, 09:25 PM