Linked list not increasing in size

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.

linkedlist.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#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


linkedlist.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "linkedlist.h"

using namespace 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;
}


node.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef NODE_H_
#define NODE_H_
#include <cstdlib>
#include <iostream>

namespace banfield_lab5 {
class node {

public:
	//Typedef
	typedef int 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.
Last edited on
I saw these 2 things:


1
2
3
4
5
linkedlist::~linkedlist(){
	for (current_ptr = head_ptr; current_ptr != NULL; current_ptr->getNext()) {
		delete current_ptr;
	}
}


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:

1
2
3
4
5
6
7
8
9
linkedlist::~linkedlist(){
	node* temp;
	current_ptr = head_ptr;
	while (current_ptr != NULL) {
		temp = current_ptr->getNext();
		delete current_ptr;
		current_ptr = temp;
	}
}
Topic archived. No new replies allowed.