Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Sep 5th, 2006, 12:45 AM   #1
bl00dninja
Programming Guru
 
bl00dninja's Avatar
 
Join Date: Oct 2004
Location: namespace std
Posts: 1,246
Rep Power: 5 bl00dninja is on a distinguished road
linked list problems

when i try to destroy the last (not tail, but the last remaining element) i get a run-time error. here's the code for those brave enough...

// dataDefinition.h

#ifndef DATADEFINITION_H
#define DATADEFINITION_H

typedef int elementDataType; 

#endif
// list.h

#ifndef list_H
#define list_H

#include "dataDefinition.h"

struct node
{
	elementDataType nodeData;
	node * next; // self referential
};

class list { // singly linked list class
public:
	list(); // constructor
	~list(); // destructor
	list(const list&); // copy constructor
	void deleteElement(); // deletes the current element
	void addElementAfterCurrent(elementDataType); // adds an element AFTER the current element
	void addElementAsHead(elementDataType);  // adds an element at the list head
	void addElementAsTail(elementDataType);  // adds an element at the list tail
	elementDataType getCurrentElementValue(); // gets data value of current element
	void moveForward(); // move forward one node in list
	bool isFirstElement(); // returns true if current element is list head
	bool isLastElement(); // returns true if current element is head tail
	bool isEmpty(); // returns true if list is empty
	int size(); // returns the size of the list
	void moveTolistHead(); // moves current node to the list head
	void showlist();  // shows list contents 
private:
	node * head; // list head
	node * current; // current node being processed
	int currentSize;
};

#endif
#include "list.h"
#include "dataDefinition.h"
#include <iostream>
using namespace std;

	//constructor**********************************************************
	list::list()
	{
		//set head to null
		head = 0;
		//set current to head
		current = head;
		//set size = 0
		currentSize = 0;
	}
	
	//destructor*************************************************************
	list::~list()
	{
		//taken care of by deleteElement()
	}
	
	//copy constructor********************************************************
	list::list(const list& nextObject)
	{
		current = head = 0;
		currentSize = nextObject.currentSize;
		node * pNext = nextObject.head;

		while(pNext->next != 0)
		{
			node * temp = new node;
			temp->nodeData = pNext->nodeData;
			temp->next = pNext->next;
			pNext = pNext->next;			
		}		
	}

	//delete the current element*****************************************************
	void list::deleteElement()
	{
		//do nothing if no elements
		if(head == 0) cout<<"\nempty list.\n"<<endl;

		//if 1 element
		else if(head->next == 0)
		{
			//drop first element
			head = 0;
			//dump that node
			delete current;
			//set current to head
			current = head;	
			//adjust list size
			currentSize--;
		}

		//if >1 element && current = head
		else if(current == head && current->next != 0)
		{
			//drop first element
			head = head->next;
			//dump that node
			delete current;
			//set current to head
			current = head;
			//adjust list size
			currentSize--;
		}

		//if in middle of list...
		else if (current != head && current->next != 0)
		{
			//temp node*
			node * temp = head;
			//find the place right before current
			while(temp->next != current)
			{
				temp = temp->next;
			}
			//connect THAT place with the next place
			temp->next = current->next;
			//get rid of current node
			delete current;
			//set current to old place
			current = temp;
			//adjust list size
			currentSize--;
		}

		//we're pointing at tail...
		else if(current != head && current->next == 0)
		{
			//set temp to head
			node * temp = head;
			//find node before current
			while(temp->next != current)
			{
				temp = temp->next;
			}
			//set temp's next to null
			temp->next = 0;
			//dump this node
			delete current;
			//reset current
			current = temp;
		}
	}
		
	
	//add after current*************************************************************
	void list::addElementAfterCurrent(elementDataType input)
	{
		//if nothing, add as head
		if(head == 0) addElementAsHead(input);
		
		//if at end, add as tail
		else if (current ->next == 0) addElementAsTail(input);
		
		//otherwise...
		else
		{
			//temp node
			node * temp = new node;
			//hold current position
			temp->next = current->next;
			//back current up some
			current->next = temp;
			//insert data
			temp->nodeData = input;
			//set current to new item
			current = current->next;
			//adjust list size
			currentSize++;
		}
	}
	
	//add as head******************************************************************
	void list::addElementAsHead(elementDataType input)
	{
		//if no elements, set head to new one
		if (head == 0)
		{
			head = new node;
			head->nodeData = input;
			head->next = 0;
			current = head;
		}

		//otherwise...
		else if(head != 0)
		{
			//new node
			node * temp = new node;
			//new node's data = paramater
			temp->nodeData = input;
			//push the old head back a bit
			temp->next = head;
			//reset head to new stuff
			head = temp;
			//set current to new element
			current = temp;
		}
		//adjust list size
		currentSize++;
	}
	
	//add to tail****************************************************************
	void list::addElementAsTail(elementDataType input)
	{
		//if no elements, we just repeat the crap above...
		if (head == 0)
		{
			head = new node;
			current = head;
			head->nodeData = input;
			head->next = 0;
		}

		//otherwise...
		else 
		{
			//new node
			node * temp = new node;
			//set start
			current = head;
			//find end of list
			while(current->next != 0)
			{
				current = current->next;
			}
			//set temp at end
			current->next = temp;
			//set tail pointer to null
			temp->next = 0;
			//insert data
			temp->nodeData = input;
			//set current to new crap
			current = temp;
		}
		//adjust list size
		currentSize++;
	}
	
	//return current's value*******************************************************
	elementDataType list::getCurrentElementValue()
	{
		//duh...
		return current->nodeData;
	}

	//move current to next element*************************************************
	void list::moveForward()
	{
		//if empty list, chide user
		if (head == 0) cout<<"empty list, try again buddy."<<endl;

		//if we're at the end, make sure the user understands the implications
		//	of moving forward (we go back to the start)
		else if (current->next == 0)
		{
			cout<<"\nwarning: end of list, want to wrap to head? (y or n)"<<endl;
			char choice = 'n';

			//get choice
			cin>>choice;
			//move current to start of list
			if(choice == 'y') current = head;
			
			//do nothing if they want to stay at the end
			else if (choice == 'n') cout<<"ok, you're gonna stay at the end"<<endl;

			//WTF!?!..the user is retarded, exit program and suggest
			//	they stay away from computers
			else 
			{
				cout<<"invalid parameter, bye."<<endl;
				exit(1);
			}
		}

		//or we can just move to the next element
		else current = current->next;
	}
	
	//is current the head?**********************************************************
	bool list::isFirstElement()
	{
		//if no elements, remind user that they suck
		if (head == 0)
		{
			cout<<"\nempty list\n"<<endl;
			return 0;
		}
		//return if they are pointing to the start
		else 
		{
			return (current == head);
		}
	}

	//is current the last element?***************************************************
	bool list::isLastElement()
	{
		//duh...there's nothing there
		if (head == 0) 
		{
			cout<<"\nempty list\n"<<endl;
			return 0;
		}

		//return if the user is pointing to the tail node
		else
		{
			return (current->next == 0);
		}
	}

	//are there elements?**************************************************************
	bool list::isEmpty()
	{
		//if head's not pointing to something real, there's nothing there
		return (head == 0);
	}
	
	//return # of elements*************************************************************
	int list::size()
	{
		return currentSize;
	}
	
	//move current element to the start of the list************************************
	void list::moveTolistHead()
	{	
		//do nothing if already at head
		if(current == head) cout<<"\n\nalready at head\n\n"<<endl;

		else
		{
			//temp node
			node * temp = current;
			//add that crap to the start (with correct paramater)
			addElementAsHead(temp->nodeData);
			//point current to old stuff (so we can trash it)
			current = temp;
			//get rid of the old crap
			deleteElement();
			//reset current to new stuff
			current = head;
		}
	}
	
	//print out list contents, and vars, etc.********************************************
	void list::showlist()
	{
		cout<<"\n\n********************************************************"<<endl;
		cout<<"size:\t"<<currentSize<<"\n"<<endl;
		cout<<"current val:\t"<<current->nodeData<<"\n"<<endl;
		cout<<"current->next:\t"<<current->next<<"\n"<<endl;

		int i = 1;
		for(node * temp = head; temp != 0; temp = temp->next)
		{
			//display that info
			cout<<"element "<<i<<"\t"<<temp->nodeData<<endl;
			i++;			
		}
		cout<<"\n\n********************************************************@"<<endl;
	}
//****************************************************************************************8
#include <iostream>
#include "list.h"
#include "dataDefinition.h"
using namespace std;

int main()
{
	list x;
	bool b =true;

	while(b)
	{
		int choice;

		cout<<"\n\nselect from the following:\n\n"<<endl;
		cout<<"1:\tadd as head\t\t2:\tadd as tail"<<endl;
		cout<<"3:\tadd after this node\t4:\tmove to next element"<<endl;
		cout<<"5:\tis first element?\t6:\tis last element?"<<endl;
		cout<<"7:\tis the list empty?\t8:\tmove current node to head"<<endl;
		cout<<"9:\tdelete current element\t10:\tquit\n\n"<<endl;

		cin>>choice;

		switch (choice)
		{
		case 1:
			{
				elementDataType in;
				cout<<"\n\nvalue?"<<endl;
				cin>>in;
				x.addElementAsHead(in);
				x.showlist();
				break;
			}
		case 2:
			{
				elementDataType in;
				cout<<"\n\nvalue?"<<endl;
				cin>>in;
				x.addElementAsTail(in);
				x.showlist();
				break;
			}
		case 3:
			{
				elementDataType in;
				cout<<"\n\nvalue?"<<endl;
				cin>>in;
				x.addElementAfterCurrent(in);
				x.showlist();
				break;
			}
		case 4:
			{
				x.moveForward();
				x.showlist();
				break;
			}
		case 5:
			{
				if(x.isFirstElement() ) cout<<"\n\nyes"<<endl;
				else cout<<"\n\nno"<<endl;
				x.showlist();
				break;
			}
		case 6:
			{
				if(x.isLastElement() ) cout<<"\n\nyes"<<endl;
				else cout<<"\n\nno"<<endl;
				x.showlist();
				break;
			}
		case 7:
			{
				if(x.isEmpty() ) cout<<"\n\nyes"<<endl;
				else cout<<"\n\nno"<<endl;
				x.showlist();
				break;
			}
		case 8:
			{
				x.moveTolistHead();
				x.showlist();
				cout<<"copy"<<endl;
				list y(x);
				y.showlist();
				break;
			}
		case 9:
			{
				x.deleteElement();
				x.showlist();
				break;
			}
		case 10:
			{
				exit(0);
				break;
			}
		default:
			{
				cout<<"invalid input"<<endl;
				break;
			}
		}//end switch
	}//end while
	

	system("PAUSE");
	return 0;
}

am i mis-using the destructor?
the copy constructor is essentially untested.

but the big problem is in the case of deleteElement() here:
case of one element in list to destroy.
//if 1 element
		else if(head->next == 0)
		{
			//drop first element
			head = 0;
			//dump that node
			delete current;
			//set current to head
			current = head;	
			//adjust list size
			currentSize--;
		}

also, how do i transfer a struct to a template? the 2nd problem, i have the syntax for everything else, yes i googled.
__________________
i put on my robe and wizard hat...

Have you ever heard of Plato, Aristotle, Socrates?...Morons.
bl00dninja is offline   Reply With Quote
Old Sep 5th, 2006, 2:39 AM   #2
Cache
Hobbyist
 
Join Date: Sep 2005
Posts: 261
Rep Power: 4 Cache is on a distinguished road
'current' is always dereferenced in 'list::showlist' even if it's invalid (currentSize == 0). You might want something along the lines of:

void list::showlist()
{
    if (currentSize)
    {
        cout<<"\n\n********************************************************"<<endl;
        cout<<"size:\t"<<currentSize<<"\n"<<endl;
        cout<<"current val:\t"<<current->nodeData<<"\n"<<endl;
        cout<<"current->next:\t"<<current->next<<"\n"<<endl;

        int i = 1;
        for(node * temp = head; temp != 0; temp = temp->next)
        {
            //display that info
            cout<<"element "<<i<<"\t"<<temp->nodeData<<endl;
            i++;            
        }
        cout<<"\n\n********************************************************@"<<endl;
    }
    else
    {
        // Don't dereference invalid pointers.
    }
}
There may be other things wrong too, that just stands out. Aslo:
template<typename Ty>
void function(const Ty& val)
{
}

// ...
struct test {};
test tester;
function(tester);
Cache is offline   Reply With Quote
Old Sep 5th, 2006, 2:51 AM   #3
The Dark
Expert Programmer
 
Join Date: Jun 2005
Posts: 852
Rep Power: 4 The Dark is on a distinguished road
A. If your list wants to have sex with other lists of the same gender, then you should be OK with that.
B. I think cache has it right, its the showlist that is crashing, not the delete, but if you are going to rely on currentSize, you had better make sure it is accurate - the last case in the deleteElement function doesn't decrement the currentSize counter.
The Dark is offline   Reply With Quote
Old Sep 5th, 2006, 2:49 PM   #4
Polyphemus_
Expert Programmer
 
Polyphemus_'s Avatar
 
Join Date: Aug 2005
Location: Rotterdam, the Netherlands
Posts: 942
Rep Power: 4 Polyphemus_ is on a distinguished road
Quote:
Originally Posted by The Dark
A. If your list wants to have sex with other lists of the same gender, then you should be OK with that.
Yeah, but never forget to do it safe :beard:
Polyphemus_ is offline   Reply With Quote
Old Sep 5th, 2006, 3:46 PM   #5
bl00dninja
Programming Guru
 
bl00dninja's Avatar
 
Join Date: Oct 2004
Location: namespace std
Posts: 1,246
Rep Power: 5 bl00dninja is on a distinguished road
thanks, thought about that at school today too, thanks, and ty for the template stuff!
__________________
i put on my robe and wizard hat...

Have you ever heard of Plato, Aristotle, Socrates?...Morons.
bl00dninja is offline   Reply With Quote
Old Feb 11th, 2008, 3:21 AM   #6
rhish.franks
Programmer
 
Join Date: Feb 2008
Location: India
Posts: 58
Rep Power: 1 rhish.franks is on a distinguished road
Re: linked list problems

I am not sure but my guid had told me once that for linked list do not use zero for making it null you should always use 'NULL' which is a inbuilt constant which equals to zero. Maybe its because you have used zero for deleting it its making problem. But not sure, just check if it works!
rhish.franks is offline   Reply With Quote
Old Feb 17th, 2008, 10:30 AM   #7
jason999x
Newbie
 
Join Date: Feb 2008
Posts: 6
Rep Power: 0 jason999x is on a distinguished road
Re: linked list problems

yea... rhish is right... the last pointer in your list will definitely point to NULL. On your delete_node code, the case for if it is last node (current !=head && current->next == 0) that last zero should be NULL; 0 could be like the first index (convention of flooring at zero) or could be some node with the value of 0.
jason999x is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
dev c++ software, template problem cairo C++ 11 Jun 2nd, 2006 12:42 PM
error of double linked list . Pacer C 4 May 24th, 2006 11:40 PM
Singly Linked List Help Firebar Java 3 May 22nd, 2005 10:56 AM
User-defined creatNode and deleteNode functions for a doubly-linked list jgs C 2 Apr 28th, 2005 8:53 AM
airport Log program using 3D linked List : problem reading from file gemini_shooter C++ 0 Mar 2nd, 2005 4:12 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 3:18 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC