C++ sList

Programming, for all ages and all languages.
Post Reply
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

C++ sList

Post by Neo »

I was just trying out an sList implementation with C++ (first time for me :)) and came across this problem. If I delete a node anywhere in between the list all nodes after that are also deleted (by the destructor).
Here is the code I have written

Code: Select all

template <class T> class sList{
private:
      T data;
      sList *next;
public:
   sList()
   {
      this->data = 0;
      this->next = 0;
   }
   
   sList(const T data)
   {
      this->data = data;
      this->next = NULL;
   }
   
   ~sList()
   {
      cout<<"Destructing Node: "<<this->data<<endl;
      delete this->next;
   }
   
   void add(const T data)
   {
      sList *travPtr = this;
      while(travPtr->next != 0)
      {
         travPtr = travPtr->next;
      }
      
      travPtr->next = new sList(data);
      this->data++;
   }
   
   void remove(const T data)
   {
      sList *travPtr = this;
      sList *delPtr = 0;
      
      while(travPtr->next != 0)
      {
         if(data == travPtr->next->data)
         {
            delPtr = travPtr->next;
            travPtr->next = delPtr->next;
            cout<<"Deleting Node : "<<delPtr->data<<endl;
            delete delPtr;
            this->data--;
            return;
         }
         travPtr = travPtr->next;
      }
   }
   
   void display()
   {
      sList *travPtr = this->next;
      cout<<"Total No. of nodes : "<<this->data<<endl;
      
      while(travPtr != NULL) {
         cout << travPtr->data << " --> ";
         travPtr = travPtr->next;
      }
      
      cout << endl;
   }
};

int main()
{
sList<int> myList;
myList.add(10);
myList.add(12);
myList.add(14);
myList.add(20);
myList.display();
myList.remove(12);
myList.display();
}
When I try to delete node 12 I see that all the other nodes after it are also being deleted by the destructor. I think it assumes that the nodes are all out of scope after this.
So first of all is this the way sLists are implemented in C++ and second how do I get this to work?
TIA
Only Human
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

(Disclaimer: It's been a while since I used C++)

You should set delPtr->next to 0 after unlinking it (but before deleting it, obviously).
Note: deleting a null pointer is perfectly safe, so the destructor doesn't need to be changed (besides removing the debug output).

About the implementation in general:
You may want to either disable copy construction or turn it into "move construction" by setting the original ->next to 0. If you don't do either of those things, all nodes after the first will be deleted multiple times if the list is passed by reference or accidentally copied...
(Alternatively, copy all tail nodes as well or implement some kind of reference counting or garbage collection)

Also, AFAIK C++ linked lists are usually implemented as (at least) two classes, one to represent the entire list and one to represent the individual nodes. That way, the empty list can more easily be represented, and the list type can contain extra values the individual nodes don't need (like a cached length, or a pointer to the last node as well as the first to make adding nodes at the end is easier)

And if you want to use your list with STL algorithms, you should also implement iterators (specifically forward iterators, IIRC).
That'll also make it possible to iterate over the nodes from outside the list class...
(See the documentation for SGI's slist for more operations you may want to implement)
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Post by Neo »

Sweet :) got that working now.

Yeah thanks for the additional info about the 2 classes approach. I was just beginning to wonder about how to maintain extra values like the last node etc. without adding it to the same sList class. So do they use friend classes for these or is there a better way?
Only Human
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

I'm not sure how it's usually done, but I'd probably use a (private) nested class[1]. Since the nodes don't need to have their own methods, it won't need to be a friend class. It can just be a simple struct with two public fields, next and value. All operations can be performed by the list class.


[1]: I'm pretty sure C++ supports those, but like I said, it's been a while :)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: C++ sList

Post by Candy »

Neo wrote:I was just trying out an sList implementation with C++ (first time for me :)) and came across this problem. If I delete a node anywhere in between the list all nodes after that are also deleted (by the destructor).
Here is the code I have written

Code: Select all

template <class T> class sList{
public:
   ~sList()
   {
      cout<<"Destructing Node: "<<this->data<<endl;
      delete this->next;
   }

   void remove(const T data)
   {
      sList *travPtr = this;
      sList *delPtr = 0;
      
      while(travPtr->next != 0)
      {
         if(data == travPtr->next->data)
         {
            delPtr = travPtr->next;
            travPtr->next = delPtr->next;
            cout<<"Deleting Node : "<<delPtr->data<<endl;
            delete delPtr;
            this->data--;
            return;
         }
         travPtr = travPtr->next;
      }
   }
};
When I try to delete node 12 I see that all the other nodes after it are also being deleted by the destructor. I think it assumes that the nodes are all out of scope after this.
Computers & compilers don't assume unless they tell you in clear words (called warnings). It's doing exactly what you tell it to.

Singly-linked list removals are moving the content of the next link to this link, unlinking the next link from the tree and THEN deleting it.
So first of all is this the way sLists are implemented in C++ and second how do I get this to work?
TIA[/quote]
Post Reply