0

I'm trying to do some programming puzzles to learn C and I'm having trouble with getting a linked list deletion to work when deleting the head node. I think the problem is super simple but I can't find it!! The problem I'm having is with the delete() function, when I try to remove the head of a linked list it doesn't remove it, but instead changes it to a garbage value.

Can anyone help me out please? Thank you so much!

Here's example output:

Generating list...
    Inserted:   0
    Inserted:   1
    Inserted:   2
    Inserted:   3
    Inserted:   4
List:
 0  1  2  3  4 
    Deleted:    4
List:
 0  1  2  3 
    Deleted:    0
List:
 8344720  1  2  3 

Here is my source code:

#include <stdlib.h>
#include <stdio.h>


typedef struct Node {
    int value;
    struct Node* next;
} node;

// Append a node to the end of the linked list
int insert(node* head, int value) {
    node* current = head;

    /* Check for sentinel value. If first element inserted, overwrite      head instead of appending. */
    if (head->value == 420) {
        head->value = value;
        head->next  = NULL;
        printf("\tInserted:\t%d\n", head->value);
        return 0;
    }

    /* Traverse to end to append node */
    while (current->next != NULL)
        current = current->next;

    /* Build new node and append to tail*/
    current->next = malloc(sizeof(node));
    current->next->value = value;
    current->next->next    = NULL;

    printf("\tInserted:\t%d\n", current->next->value);
    return 0;
}

/* Accept a number and delete all nodes containing that value */
int del(node* head, int value){
    node* curr = head;
    node* prev = NULL;
    node* del  = NULL;

    printf("\tDeleted:\t%d\n", value);

    if (head == NULL) {
        printf("Can't delete value from empty list!\n");
        return 1;
    }

    /* Search list remove all instances of value. Watch for edge cases. */ 
    while (curr != NULL) {
        if (curr->value == value){
            /* Head case (lol) */
            if (curr == head) {
                del        = head;
                head       = head->next;
                curr       = head;
                free(del);
            }
            /* Tail case */
            else if (curr->next == NULL) {
                del        = curr;
                curr       = prev;
                curr->next = NULL;
                free(del);
                return 0;     /* End of list, break out of loop to avoid segfaulting */
            }
            /* Body case (base case) */
            else {
                del        = curr;
                curr       = curr->next;
                prev->next = curr;
                free(del);
            }
        }
        prev = curr;
        curr = curr->next;
    }

    return 0;
}

/* Accept head pointer and print until end of list */
int traverse(node* head) {
    node* current = head;

    if (head == NULL){
        printf("Can't traverse null list!\n");
        return 1;
    }

    printf("List:\n");
    while(current != NULL) {
        printf(" %d ", current->value);
        current = current->next;
    }
    printf("\n");

    return 0;
}

/* Let's begin our crazy experiment.... */
int main() {
    node* head  = NULL;
    head        = malloc(sizeof(node));
    head->value = 420;
    head->next  = NULL;


    printf("Generating list...\n");

    int value;
    for (value = 0; value < 5; value++)
        insert(head, value);

    traverse(head);

    del(head, 4);
        traverse(head);

    del(head, 0);
        traverse(head);

    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • 3
    Standard beginner's error. `head = head->next`. C is pass by value. So that line does not change the original `head` value that the caller sees but only a *local copy* of the `head` value. – kaylum Sep 16 '16 at 00:40
  • 1
    Possible duplicate of [How do I modify a pointer that has been passed into a function in C?](http://stackoverflow.com/questions/766893/how-do-i-modify-a-pointer-that-has-been-passed-into-a-function-in-c) – kaylum Sep 16 '16 at 00:48

1 Answers1

1

You are modifying the head inside the del() function and using the old head from the main(). You need to pass the address of the head to del and modify it so that the change will reflect in main. You may need something like this.

int del(node **head, int value){ node* curr = *head; ....

And from the main

del(&head);

aneesh jose
  • 381
  • 2
  • 8