Doubly Linked List Help

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Feb 2009
Posts: 136
Reputation: lancevo3 is an unknown quantity at this point 
Solved Threads: 0
lancevo3 lancevo3 is offline Offline
Junior Poster

Doubly Linked List Help

 
0
  #1
Sep 2nd, 2009
I am working on a doubly linked list assignment for my class and I am getting a segmentation fault on my test for the copy constructor. I don't know if the problem lies within my copyList method or my copy constructor logic. Any assistance be great.

Here is my header file and link to the assignment.
http://turing.cs.niu.edu/~t90kjm1/CS...s01340f09.html

  1. #ifndef LIST_H
  2. #define LIST_H
  3.  
  4. #include <iostream>
  5.  
  6. template <class T>
  7. class List;
  8.  
  9. template <class T>
  10. std::ostream& operator<<(std::ostream&, const List<T>&);
  11.  
  12. template <class T>
  13. struct LNode
  14. {
  15. T data;
  16. LNode<T>* prev;
  17. LNode<T>* next;
  18.  
  19. LNode(const T&);
  20. };
  21.  
  22. template <class T>
  23. LNode<T>::LNode(const T& newdata)
  24. {
  25. data = newdata;
  26. prev = next = NULL;
  27. }
  28.  
  29. template <class T>
  30. class List
  31. {
  32. friend std::ostream& operator<< <>(std::ostream&, const List<T>&);
  33.  
  34. private:
  35. LNode<T>* head;
  36. LNode<T>* tail;
  37. public:
  38. List();
  39. ~List();
  40. List(const List<T>&);
  41. LNode<T>* copyList(LNode<T>*);
  42. List<T>& operator=(const List<T>&);
  43. void clear();
  44. int size() const;
  45. bool empty() const;
  46. const T& front() const;
  47. T& front();
  48. const T& back() const;
  49. T& back();
  50. void push_front(const T&);
  51. void push_back(const T&);
  52. void pop_front();
  53. void pop_back();
  54. bool operator==(const List<T>&) const;
  55. bool operator<(const List<T>&) const;
  56. };
  57.  
  58. template <class T>
  59. List<T>::List()
  60. {
  61. head = NULL;
  62. tail = NULL;
  63. }
  64.  
  65. template <class T>
  66. List<T>::~List()
  67. {
  68. clear();
  69. }
  70.  
  71. template <class T>
  72. List<T>::List(const List<T>& oldList)
  73. {
  74. head = copyList(oldList.head);
  75. tail = copyList(oldList.tail);
  76. }
  77.  
  78. template <class T>
  79. LNode<T>* List<T>::copyList(LNode<T>* ptr)
  80. {
  81. LNode<T>* newNode;
  82.  
  83. if(ptr==NULL)
  84. return NULL;
  85. else
  86. {
  87. newNode = new LNode<T>(ptr->data);
  88. newNode->prev = copyList(ptr->prev);
  89. newNode->next = copyList(ptr->next);
  90. }
  91. return newNode;
  92. }
  93.  
  94. template <class T>
  95. List<T>& List<T>::operator=(const List<T>& rightOp)
  96. {
  97. if (this != &rightOp)
  98. {
  99. clear();
  100. head = copyList(rightOp.head);
  101. tail = copyList(rightOp.tail);
  102. }
  103. return *this;
  104. }
  105.  
  106. template <class T>
  107. void List<T>::clear()
  108. {
  109. while(!empty())
  110. pop_front();
  111. }
  112.  
  113. template <class T>
  114. int List<T>::size() const
  115. {
  116. LNode<T>* ptr = head;
  117. int count = 0;
  118.  
  119. while(ptr != NULL)
  120. {
  121. count++;
  122. ptr = ptr->next;
  123. }
  124. return count;
  125. }
  126.  
  127. template <class T>
  128. bool List<T>::empty() const
  129. {
  130. if(head == NULL or tail == NULL)
  131. return true;
  132. else
  133. return false;
  134. }
  135.  
  136. template <class T>
  137. const T& List<T>::front() const
  138. {
  139. return head->data;
  140. }
  141.  
  142. template <class T>
  143. T& List<T>::front()
  144. {
  145. return head->data;
  146. }
  147.  
  148. template <class T>
  149. const T& List<T>::back() const
  150. {
  151. return tail->data;
  152. }
  153.  
  154. template <class T>
  155. T& List<T>::back()
  156. {
  157. return tail->data;
  158. }
  159.  
  160. template <class T>
  161. void List<T>::push_front(const T& item)
  162. {
  163. LNode<T>* newNode;
  164.  
  165. if(!empty())
  166. {
  167. newNode->prev = NULL;
  168. newNode->next = head;
  169. head->prev = newNode;
  170. head = newNode;
  171. }
  172. else
  173. {
  174. newNode->prev = NULL;
  175. newNode->next = head;
  176. tail = newNode;
  177. head = newNode;
  178. }
  179. }
  180.  
  181. template <class T>
  182. void List<T>::push_back(const T& item)
  183. {
  184. LNode<T>* newNode;
  185. newNode = new LNode<T>(item);
  186.  
  187. newNode->next = NULL;
  188. newNode->prev = tail;
  189. if(empty())
  190. head = newNode;
  191. else
  192. tail->next = newNode;
  193. tail = newNode;
  194. }
  195.  
  196. template <class T>
  197. void List<T>::pop_front()
  198. {
  199. if(size() > 1)
  200. {
  201. LNode<T>* delNode = head;
  202. head = delNode->next;
  203. head->prev = NULL;
  204. delete delNode;
  205. }
  206. if(size() == 1)
  207. {
  208. LNode<T>* delNode = head;
  209. head = delNode->next;
  210. tail = NULL;
  211. delete delNode;
  212. }
  213. }
  214.  
  215. template <class T>
  216. void List<T>::pop_back()
  217. {
  218. if(size() > 1)
  219. {
  220. LNode<T>* delNode = tail;
  221. tail = delNode->prev;
  222. tail->next = NULL;
  223. delete delNode;
  224. }
  225. if(size() == 1)
  226. {
  227. LNode<T>* delNode = tail;
  228. tail = delNode->prev;
  229. head = NULL;
  230. delete delNode;
  231. }
  232. }
  233.  
  234. template <class T>
  235. bool List<T>::operator==(const List<T>& rightOp) const
  236. {
  237. LNode<T>* p1;
  238. LNode<T>* p2;
  239.  
  240. while(p1 != NULL and p2 != NULL)
  241. {
  242. if(p1->data != p2->data)
  243. return false;
  244. }
  245. if(p1 == NULL and p2 == NULL)
  246. return true;
  247. else
  248. return false;
  249. }
  250.  
  251. template <class T>
  252. bool List<T>::operator<(const List<T>& rightOp) const
  253. {
  254. LNode<T>* p1;
  255. LNode<T>* p2;
  256.  
  257. while(p1 != NULL and p2 != NULL)
  258. {
  259. if(p1->data < p2->data)
  260. return true;
  261. if(p1->data > p2->data)
  262. return false;
  263. }
  264. if(p2 == NULL)
  265. return false;
  266. else
  267. return true;
  268. }
  269.  
  270. template <class T>
  271. std::ostream& operator<<(std::ostream& leftOp, const List<T>& rightOp)
  272. {
  273. LNode<T>* current;
  274.  
  275. for (current=rightOp.head; current != NULL; current = current->next)
  276. std::cout << current->data << " ";
  277. return leftOp;
  278. }
  279. #endif /*LIST_H*/
Reply With Quote Quick reply to this message  
Join Date: Aug 2009
Posts: 66
Reputation: Protuberance will become famous soon enough Protuberance will become famous soon enough 
Solved Threads: 14
Protuberance's Avatar
Protuberance Protuberance is offline Offline
Junior Poster in Training

Re: Doubly Linked List Help

 
0
  #2
Sep 2nd, 2009
I dont understand why you use copyList method for just copying two pointers...
For copying one list to another you must copy head and tail pointers.
So your copy constructror will be like this
  1. template <class T>
  2. List<T>::List(const List<T>& oldList)
  3. {
  4. this->head = oldList.head;
  5. this->tail = oldList.tail;
  6. }
And another one - c++ does not have "and" operator. Just use "&&" operator

P.S. I advise to clean "copyList" method. He can be replaced assignment of head and tail pointers.
Last edited by Protuberance; Sep 2nd, 2009 at 4:37 pm.
"If a problem can be decided - it is not needed to worry, and if to decide it is impossible - worrying is useless." (с)
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 136
Reputation: lancevo3 is an unknown quantity at this point 
Solved Threads: 0
lancevo3 lancevo3 is offline Offline
Junior Poster

Re: Doubly Linked List Help

 
0
  #3
Sep 2nd, 2009
I went ahead and updated my copy consturctor as you said and that worked great, thank you!

On this part of my output I am getting an error:


Testing clear() of non-empty list...
list 1 (size 0):
list 2 (size 4): 0 32178176 32178208 32178240

The error is with the list 2.

This is the code from the driver for that line.

  1. cout << "list 2 (size " << list2.size() << "): " << list2 << endl << endl;
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,699
Reputation: Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all 
Solved Threads: 272
Lerner Lerner is offline Offline
Posting Virtuoso

Re: Doubly Linked List Help

 
0
  #4
Sep 2nd, 2009
I recommend you think twice about simple copying of head and tail pointers to copy one list to another. This is called shallow copy and works okay in simple programs but it can quickly cause problems if you aren't aware of what is happening. In particular, under this scenario if either list is deleted then the other list is useless because there is now no longer any place in memory to point to.

I recommend doing hard copy within the copy constructor, copy function. That way each list has it's own memory, even if it contains the same information.

Don't try to copy an empty list. If the list to copy is empty, then return from the function/constructor.
Klatu Barada Nikto
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 147
Reputation: GDICommander is an unknown quantity at this point 
Solved Threads: 19
GDICommander's Avatar
GDICommander GDICommander is offline Offline
Junior Poster

Re: Doubly Linked List Help

 
0
  #5
Sep 2nd, 2009
If your operator=() works, extract the code that creates a new list with the one provided as a parameter and use it in your copy constructor. Search for the refactoring tip Extract Method.
Last edited by GDICommander; Sep 2nd, 2009 at 7:48 pm.
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 136
Reputation: lancevo3 is an unknown quantity at this point 
Solved Threads: 0
lancevo3 lancevo3 is offline Offline
Junior Poster

Re: Doubly Linked List Help

 
0
  #6
Sep 2nd, 2009
I tried the copy constructor posted and its giving me a program crash this just doesn't look right to me either any ideas whats up with it?

  1. template <class T>
  2. List<T>::List(const List<T>& oldList)
  3. {
  4. this->head = oldList.head;
  5. this->tail = oldList.tail;
  6. }
Reply With Quote Quick reply to this message  
Join Date: Aug 2009
Posts: 66
Reputation: Protuberance will become famous soon enough Protuberance will become famous soon enough 
Solved Threads: 14
Protuberance's Avatar
Protuberance Protuberance is offline Offline
Junior Poster in Training

Re: Doubly Linked List Help

 
0
  #7
Sep 3rd, 2009
Originally Posted by lancevo3 View Post
I tried the copy constructor posted and its giving me a program crash this just doesn't look right to me either any ideas whats up with it?

  1. template <class T>
  2. List<T>::List(const List<T>& oldList)
  3. {
  4. this->head = oldList.head;
  5. this->tail = oldList.tail;
  6. }
What kind of error did you get?
AV(Access Violation)
Exception
Segmentation fault
?

If you don't try to copy an empty list, that code works correctly.
For empty list just place condition before assignment
  1. template <class T>
  2. List<T>::List(const List<T>& oldList)
  3. {
  4. if(!oldList.isEmpty())
  5. {
  6. this->head = oldList.head;
  7. this->tail = oldList.tail;
  8. }
  9. else
  10. throw "Empty list";
  11. }
  12.  
  13. //isEmpty method
  14. template <class T>
  15. bool List<T>::isEmpty() const
  16. {
  17. return head == NULL;
  18. }

Or if you wanna copy list, then delete it, then use copy method. Like that
  1. template <class T>
  2. void List<T>::copyList(const List<T> &source)
  3. {
  4. //condition for empty list
  5. LNode<T> *source_head_temp = source.head;
  6. while(source_head_temp)
  7. {
  8. push_back(source_head_temp->data);
  9. source_head_temp = source_head_temp->next;
  10. }
  11. }
I hope it helps you.
"If a problem can be decided - it is not needed to worry, and if to decide it is impossible - worrying is useless." (с)
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,699
Reputation: Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all 
Solved Threads: 272
Lerner Lerner is offline Offline
Posting Virtuoso

Re: Doubly Linked List Help

 
0
  #8
Sep 3rd, 2009
Mock up copy constructor. Code untested. I'm comfortable with the logic and the comments. Adjustable to your needs as desired.
  1. //use deep copy protocol to copy rhs into a new List using a copy constructor.
  2. //type Node is used to create type List.
  3. //List is doubly linked
  4. //List always adds to the end
  5. List(const List & rhs)
  6. {
  7. if(rhs.count == 0) //rhs is empty, so assign default values to new List member variables
  8. {
  9. count = 0;
  10. firstNode = NULL;
  11. lastNode = NULL;
  12. }
  13. else
  14. {
  15. //declare a Node to run rhs, start with first node in rhs.
  16. Node * current = rhs.firstNode;
  17.  
  18. //assign default values to member variables of new List
  19. count = 0;
  20. firstNode = lastNode = NULL;
  21.  
  22. //use a loop to copy data from rhs into new List one Node at a time
  23. while(current != NULL)
  24. {
  25. //create a new Node to enter into the new List
  26. Node newNode = new Node;
  27. newNode->prev = NULL;
  28. newNode->next = NULL;
  29. newNode->data = current->data;
  30.  
  31. //add new Node to new List
  32. if(count == 0) //new list is empty
  33. firstNode = lastNode = newNode;
  34. else //add new Node to end of new List
  35. {
  36. lastNode->next = newNode;
  37. newNode->prev = lastNode;
  38. lastNode = lastNode->next;
  39. }
  40.  
  41. //increment count and get next node in rhs to copy into new List
  42. ++count;
  43. current = current->next;
  44. }
  45. }
  46. }
Klatu Barada Nikto
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 136
Reputation: lancevo3 is an unknown quantity at this point 
Solved Threads: 0
lancevo3 lancevo3 is offline Offline
Junior Poster

Re: Doubly Linked List Help

 
0
  #9
Sep 5th, 2009
I been able to get this list going for the most part but I am getting a segmentation fault and I believe its being caused by my equality operator, I though I had everything coded right. Any thoughts?

  1. template <class T>
  2. bool List<T>::operator==(const List<T>& rightOp) const
  3. {
  4. LNode<T>* p1;
  5. LNode<T>* p2;
  6.  
  7. while(p1 != NULL and p2 != NULL)
  8. {
  9. if(p1->data != p2->data)
  10. return false;
  11. }
  12. if(p1 == NULL and p2 == NULL)
  13. return true;
  14. else
  15. return false;
  16. }
Reply With Quote Quick reply to this message  
Join Date: Mar 2008
Posts: 675
Reputation: Sky Diploma is a splendid one to behold Sky Diploma is a splendid one to behold Sky Diploma is a splendid one to behold Sky Diploma is a splendid one to behold Sky Diploma is a splendid one to behold Sky Diploma is a splendid one to behold 
Solved Threads: 100
Sky Diploma's Avatar
Sky Diploma Sky Diploma is offline Offline
Practically a Master Poster

Re: Doubly Linked List Help

 
0
  #10
Sep 5th, 2009
firstly,

logical and in C++ is represented by '&&' so you will need to have.

  1. while(p1 != NULL and p2 != NULL)

Changed to


  1. while(p1 != NULL && p2 != NULL)

The same applies to the if loop below as well.


Secondly, Your Logical error is that you make 2 nodes p1 and p2, but donot assign any location for them to point to.

So it goes on looping infinitely i guess.

you should instead do something like this.

  1. p1= this-> head;
  2. p2= rightOp.head;
Then let it go through the while loop and. During the while loop checks you will need to move to the next position to.

so

  1. while(p1 != NULL and p2 != NULL)
  2. {
  3. if(p1->data != p2->data)
  4. return false;
  5.  
  6. p1= p1->next;
  7. p2= p2->next;
  8. }
  9. return true;
Last edited by Sky Diploma; Sep 5th, 2009 at 3:49 am. Reason: Code corrections
1. Please Mark Your Thread as Solved After Getting Your Answers.
2. Please Use CODE TAGS .
Reply With Quote Quick reply to this message  
Reply

Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC