Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!news.glorb.com!news-out.readnews.com!news-xxxfer.readnews.com!panix!not-for-mail From: Ruben Safir Newsgroups: comp.lang.c++ Subject: Destructors can copying objects Date: Sat, 2 Apr 2011 12:58:43 +0000 (UTC) Organization: PANIX Public Access Internet and UNIX, NYC Lines: 194 Message-ID: NNTP-Posting-Host: www2.mrbrklyn.com Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: reader1.panix.com 1301749123 1029 96.57.23.82 (2 Apr 2011 12:58:43 GMT) X-Complaints-To: abuse@panix.com NNTP-Posting-Date: Sat, 2 Apr 2011 12:58:43 +0000 (UTC) X-Blackjet: Blackjet is a Yankee Fan X-DRMisTHEFT: Use GNU Linux today X-From: A Dark Cloud X-LOCATION: Brooklyn NY - Forget abou' it! X-NYLXS: Really - yah think computers are supposed to be broken? User-Agent: Pan/0.133 (House of Butterflies) Xref: x330-a1.tempe.blueboxinc.net comp.lang.c++:2996 I am creating a linked link program which created a segmentation fault and a core at the end of the program. The program is trying to delete an already deleted object, and I can't seem to protect my program from this. I fixed the problem by sending an object to a function by reference rather than by value, but I'm not satisfied with the solution. The list has node objects namespace chainlist { /* * ===================================================================================== * Class: Node * Description: This is a node in the "List" Link List * ===================================================================================== */ template < class unk > class Node { public: // ==================== LIFECYCLE ======================================= /* constructor */ Node( unk value, Node *item_to_link_to = 0); Node ( const Node &other ); /* copy constructor - Need to write this! */ ~Node (); /* destructor */ /* ==================== ACCESSORS ======================================= */ inline unk* value ()const{ return value_; } inline Node * next()const { return next_; } inline void value(unk *); inline void value(unk); inline void next(Node *); /* ==================== MUTATORS ======================================= */ /* ==================== OPERATORS ======================================= */ Node& operator=( const Node &other ); // assignment operator unk& operator*(){ //gain access to real value return *(value()); } unk& operator*(unk); protected: /* ==================== DATA MEMBERS ======================================= */ private: /* ==================== DATA MEMBERS ======================================= */ unk * value_ ; Node * next_; }; /* ----- end of template class Node ----- */ And they are controlled by a List Object template < class T > class List { public: /* ==================== LIFECYCLE ======================================= */ List(): front_(0),end_(0), cursor_(0), size_(0){} /* constructor */ void remove_all(); ~List(); /* ==================== ACCESSORS ======================================= */ int size()const { return size_; } inline Node* const &front()const{ return front_;} inline Node* &endd(){return end_;} inline Node *& cursor(){return cursor_;} inline void cursor(Node * a){ cursor_ = a; } inline void endd(Node *a){ end_ = a; } inline void front(Node *a){ front_ = a; } inline void display(); /* ==================== MUTATORS ======================================= */ inline void sizeup(){ ++size_; } inline void sizedown(){ --size_; } void insert_front( T value); //add a node to the front void insert(T value, Node * &place_after_this); //add a new node after the Node given and return the new node void insert(T value); //add a new node at the end of the list void insert_end(T value); // Add a new node to the end void find_value(T value); //find a value from it's first occurance in the list Node& find_next_value(const T& value, Node& last_node_searched); //find a value in the list after the //current node which is not searched void remove_node_by_value(T value); void remove_node_by_node(Node cur); void remove_node_front(); void remove_node_end(); /* ==================== OPERATORS ======================================= */ protected: /* ==================== DATA MEMBERS ======================================= */ private: /* ==================== DATA MEMBERS ======================================= */ Node * front_; Node * end_; Node * cursor_; int size_; }; /* ---------- end of template class Lists ---------- */ The destructors are defined as follows template Node::~Node(){ if(value_) delete value_; std::cout << "Delete Node" << std::endl; } template List::~List(){ remove_all(); std::cout << "Deleted All*************" << std::endl; } And remove all looks like this template< class T> void List::remove_all(){ cursor() = front(); Node * tmp; while(cursor() != endd()){ tmp = cursor(); cursor() = cursor()->next(); if(tmp) delete tmp; } std::cout << "\n\nReached the End\n\n"; tmp = cursor(); //last node if(tmp) delete tmp; cursor() = 0; //park the cursor } I created a large list to test my find functions and passed it by value to main. Then passed it by value to a find testing function. when the program ends, it seems to delete all the nodes from the List twice, once from the local program and then from main. Sending it by reference fixed the problem, but I can see other instances where this can be a huge problem, such as if I decide o delete an individual node from the list. There has to be a better strategy for handling this issue. ~