I'm trying to implement a linked list using my own node class. I've created functions to add to the head and tail, return the size of the linked list as well as the value stored within the current pointer.
However, my problem is that when I wrote a test program to see whether my list worked, my list did not appear to increase in size past 1 item in the list.
this is the test program I wrote:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int main() {
int counter,
data;
linkedlist *my_list = new linkedlist();
cout << my_list->size() << endl;
for (counter = 0; counter < 5; counter++) {
cout << "Please enter a number: " << endl;
cin >> data;
my_list->addToTail(data);
cout << my_list->getCurrent() << endl;
cout << my_list->size() << endl;
}
//cout << *my_list << endl;
//delete my_list;
return 0;
}
But this is the output I get:
"$ ./list_test
0
Please enter a number:
0
0
1
Please enter a number:
1
1
1
Please enter a number:
2
2
1
Please enter a number:
3
3
1
Please enter a number:
4
4
1"
I'll include the .h and .cpp file for the linked list as well as the .h file for the node class for reference.
#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_
#include <cstdlib>
#include "node.h"
using banfield_lab5::node;
namespace banfield_lab5 {
class linkedlist{
public:
// Typedefs
typedef std::size_t size_type;
// onstructor
linkedlist(node* init_head = NULL, node* init_current = NULL, node* init_tail = NULL);
//Deconstructor
~linkedlist();
//Member function that returns the size of the linked list
size_type size();
//Mutator Member functions to add to the head, tail of the list
void addToHead(const node::value_type& entry);
void addToTail(const node::value_type& entry);
//Accessor Member function to retrieve the data in the linked list
node::value_type getCurrent() const;
private:
size_type used;
node* head_ptr;
node* tail_ptr;
node* current_ptr;
};
std::ostream& operator<<(std::ostream& out, const linkedlist& a);
}
#endif
#include "linkedlist.h"
usingnamespace banfield_lab5;
//Constructor
linkedlist::linkedlist(node* init_head, node* init_current, node* init_tail) {
head_ptr = init_head;
current_ptr = init_current;
tail_ptr = init_tail;
}
//Deconstructor
linkedlist::~linkedlist(){
for (current_ptr = head_ptr; current_ptr != NULL; current_ptr->getNext()) {
delete current_ptr;
}
}
//Postcondition: Returns the size of the linked list
linkedlist::size_type linkedlist::size(){
node* temp;
temp = current_ptr;
used = 0;
for (current_ptr = head_ptr; current_ptr != NULL; current_ptr = current_ptr->getNext()) {
used++;
return used;
}
current_ptr = temp;
return 0;
}
//Postcondition: Adds an entry into the linked list at the head of the list
void linkedlist::addToHead(const node::value_type& entry) {
if (head_ptr == NULL) {
head_ptr = new node(entry, NULL, NULL);
tail_ptr = head_ptr;
current_ptr = tail_ptr;
}
else {
head_ptr = new node(entry, current_ptr, NULL);
current_ptr->setPrevious(head_ptr);
current_ptr = head_ptr;
}
}
//Postcondition: Adds an entry into the linked list at the tail of the list
void linkedlist::addToTail(const node::value_type& entry) {
if (head_ptr == NULL) {
head_ptr = new node(entry, NULL, NULL);
tail_ptr = head_ptr;
current_ptr = head_ptr;
}
else {
tail_ptr = new node(entry, NULL, current_ptr);
current_ptr->setNext(tail_ptr);
current_ptr = tail_ptr;
}
}
//Postcondition: The value that is stored within the current pointer is returned
node::value_type linkedlist::getCurrent() const{
return current_ptr->getData();
}
std::ostream& operator<<(std::ostream& out, const linkedlist& ll){
out << ll.getCurrent(); //This will change to ll.printList() when it is implemented
return out;
}
#ifndef NODE_H_
#define NODE_H_
#include <cstdlib>
#include <iostream>
namespace banfield_lab5 {
class node {
public:
//Typedef
typedefint value_type;
//Constructor
node(const value_type& init_data = value_type(), node* init_next = NULL, node* init_previous = NULL);
//Deconstructor
~node();
//Member function to set the data
void setData(const value_type& new_data);
//Member functions to set the next and previous link
void setNext(node* new_link);
void setPrevious(node* new_link);
//Constant member function to retrieve the current data
value_type getData() const;
//Member functions to retrieve the next link
const node* getNext() const;
node* getNext();
//Member functions to retrieve the previous link
const node* getPrevious() const;
node* getPrevious();
private:
value_type data;
node* next;
node* previous;
};
//Overloaded Non-Member Operations
std::ostream& operator<<(std::ostream& out, const node& data);
}
#endif /* NODE_H_ */
I'm sure it's probably something simple that I've overlooked . But I'm still relatively new to the concept of dynamic memory allocation so any help or advice would be greatly appreciated.
If you delete current_ptr, then you will not be able to [safely] do current_ptr->getNext() to get the next node -- since current_ptr's node will no longer exist. You will have to find a different way to do this. Usually this is done by taking current_ptr->next and putting it in a temporary variable, then deleting the node.
1 2 3 4 5
// in linkedlise::size
for (current_ptr = head_ptr; current_ptr != NULL; current_ptr = current_ptr->getNext()) {
used++;
return used;
}
Remember ther return exits the function. Also note that return used; is in the loop body and therefore will happen every iteration. Therefore, this for loop will never run more than once, because as soon as you hit that return statement, the loop (and function) will stop, and the value currently in 'used' will be returned. Therefore, it is impossible for this function to return anything higher than 1.
After that I stopped looking as that 2nd thing seems to be the source of your problem.
@Disch Ah, you are definitely right. I was convinced that there was a problem with the addToTail() function that I was blind to the obvious answer haha.
Thanks for that, I'm really grateful :)
Also, I see what you mean about the deconstructor. I wasn't entirely sure what you meant about implementing so I did a google search for linked list deconstructor and found this code which seems to work and do what you suggested: