Thread: Deleting node from linked list, need explanation

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    7

    Deleting node from linked list, need explanation

    Hi Everyone, I have been playing around with linked lists and I got stuck with one issue. The issue is following:
    lets say you have two structures and couple of functions, such as:
    Code:
    typedef struct node *link;
    struct node {
    	char data;
    	link next;
    	link prev;
    };
    typedef struct Root *root;
    struct Root {
    	int size;
    	link first;
    	link last;
    };
    
    root InitList(void);
    root AddFront(root list, char value);
    link FindNode(root list, char value);
    
    void FindNodeAndDelete(root list, char value);
    void DeleteNode(root list, link node);
    void PrintList(root list);
    
    link FindNode(root list, char value) {
    	link node = NULL;
    	if (list->first == NULL) {
    		printf("List is empty\n");
    		return NULL;
    	}
    	else {
    		node = list->first;
    		while (node != NULL) {
    			if (node->data == value)
    				return node;
    			node = node->next;
    		}
    	}
    	return NULL;
    }
    void FindNodeAndDelete(root list, char value) {
    	link node, temp;
    	node = FindNode(list, value);
    	node->next->prev = node->prev;
    	node->prev->next = node->next;
    	free(node);
    }
    
    void DeleteNode(root list, link node) {
    	node->next->prev = node->prev;
    	node->prev->next = node->next;
    	free(node);
    }
    If I use DeleteNode function I do remove link from the list without an issue. On the other hand when I use FindNodeAndDelete function, I do locate node that needs to be removed. However once I start rearranging its preceding and subsequent nodes I get Segmentation Fault from the compiler. Can some one please explain why is this happening?
    How FindNodeAndDelete function should look so it can be executed without error ?
    Regards

  2. #2
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Since you are FindNodefunction returns NULL of nothing found. You should check for the return value in the FindNodeAndDelete before you try to dereference them. It looks like that you are dereferencing the NULL node and hence the seg fault.

    ssharish

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    7
    I checked it, it will return NULL in FindNode function only if node that I am looking for is not located. However if I substitute value of a node that exists the lets say, in the middle of the list, function will return it. However on the next step when I am rearranging links of next and prev nodes I am getting Segmentation fault error???
    Should I post all the code so any one can run it ?
    cheers

  4. #4
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Post your code, lets have a look. I can see that there is a pit fall in your code, which you have posted here. But let me make sure, if i am right, after looking at your complete code.

    ssharish

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    7
    Excellent, the code is following:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node *link;
    struct node {
    	char data;
    	link next;
    	link prev;
    };
    
    typedef struct Root *root;
    struct Root {
    	int size;
    	link first;
    	link last;
    };
    
    root InitList(void);
    root AddFront(root list, char value);
    link FindNode(root list, char value);
    void FindNodeAndDelete(root list, char value);
    void DeleteNode(root list, link node);
    void PrintList(root list);
    
    
    int main(void) {
    	root list;
    	link node;
    
    	list = InitList();
    	list = AddFront(list, 'M');
    	list = AddFront(list, 'A');
    	list = AddFront(list, 'B');
    	
            /* This is where segmentation fault occurs */
     	FindNodeAndDelete(list, 'A');
    
    	PrintList(list);
    	node = FindNode(list, 'A');
     
            /* Ffunction below removes node without any issues*/
    	/* DeleteNode(list, node); */
    	PrintList(list);
    	return 0;
    }
    
    root InitList(void) {
    	root list;
    	if ((list=(root)malloc(sizeof(root))) == NULL) {
    		fprintf(stderr, "Not enough memory to allocate root\n");
    		exit(1);
    	}
    	list->first=list->last = NULL;
    	list->size = 0;
    	return list;
    }
    
    root AddFront(root list, char value) {
    	link newNode;
    	if ((newNode=(link)malloc(sizeof(link))) == NULL) {
    		fprintf(stderr, "Not enough memory to new node\n");
    		exit(1);
    	}
    	if (list->first == NULL) {
    			newNode->data = value;
    			newNode->next = list->first;
    			newNode->prev = NULL;
    			list->last = newNode;
    			list->first = newNode;
    			++list->size;
    			return list;
    	}
    
    	newNode->data = value;
    	newNode->next = list->first;
    	newNode->prev = NULL;
    	list->first = newNode;
    	++list->size;
    	return list;
    }
    
    link FindNode(root list, char value) {
    	link node = NULL;
    	node = list->first;
    
    	if (node == NULL) {
    		printf("list is empty\n");
    		return NULL;
    	}
    	else {
    			while (node != NULL) {
    			if (node->data == value)
    				return node;
    			node = node->next;
    		}
    	}
    	printf("Node is not located returning NULL\n");
    	return NULL;
    	
    }
    void FindNodeAndDelete(root list, char value) {
    	link node;
    	node = FindNode(list, value);
    	if (node == NULL)
    		printf("Element is not located\n");
    	else {
    		printf("Node located, its value is &#37;c\n", node->data);
    		node->next->prev = node->prev;
    		node->prev->next = node->next;
    		free(node);
    	}
    }
    
    void PrintList(root list) {
    	link element;
    	element = list->first;
    	
    	if (element == NULL) 
    		printf("List is empty\n");
    	else 
    		while (element != NULL) {
    			printf("Node's value is %c\n", element->data);
    			element = element->next;
    		}
    	printf("List size is %d\n", list->size);
    
    }
    Cheers
    Last edited by prihod; 04-06-2008 at 10:29 PM.

  6. #6
    Registered User dinjas's Avatar
    Join Date
    Feb 2005
    Location
    Vancouver, Washington
    Posts
    40
    I think the main problem you are having is in your AddFront function.
    You are inserting at the beginning of the list but dont update the previous
    node value for the old first element. Something like:

    Code:
    newNode->prev = NULL;
    list->first->prev = newNode;
    list->first = newNode;
    in AddFront should fix it.

    Also, maybe consider something like:

    Code:
    void FindNodeAndDelete(root list, char value) {
        DeleteNode(list, FindNode(list, value));
    }
    dinjas
    straight off the heap

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. deleting node in linked list
    By cstudent in forum C Programming
    Replies: 1
    Last Post: 05-15-2008, 02:42 AM
  2. singly linked circular list
    By DarkDot in forum C++ Programming
    Replies: 0
    Last Post: 04-24-2007, 08:55 PM
  3. Reverse function for linked list
    By Brigs76 in forum C++ Programming
    Replies: 1
    Last Post: 10-25-2006, 10:01 AM
  4. Problems with deleting a node in a singly linked list
    By omishompi in forum C++ Programming
    Replies: 7
    Last Post: 02-23-2006, 06:27 PM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM