8
votes

I'm writing a basic linked list program in C and having a bit of trouble with deletion. Here's what I have:

#include <stdio.h>

struct node * delete(struct node * head, struct node * toDelete);
void print(struct node * head);

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

int main(int argc, const char * argv[]) {

    struct node node1, node2, node3;
    struct node *head = &node1;

    node1.value = 1;
    node1.next = &node2;

    node2.value = 2;
    node2.next = &node3;

    node3.value = 3;
    node3.next = (struct node *) 0;

    print(head);

    delete(head, &node3);

    print(head);

    return 0;
}

struct node * delete(struct node * head, struct node * toDelete) {
    //if to delete is head
    if (head == toDelete) {
        head = head->next;

    } else {
        //find node preceding node to delete
        struct node *current = head;
        while (current->next != toDelete) {
            current = current->next;
        }
        current = current->next->next;
    }
    return head;
}

void print(struct node * head) {
    struct node *current = head;

    while (current != (struct node *) 0) {
        printf("%i\n", current->value);
        current = current->next;
    }
}

Question #1: So I tried to write:

delete(head, node3);

but xCode wanted me to add "&" in front of "node3". Is it generally true that when I define a function to take a pointer, I need to pass in the memory address?

Question #2:

My print function works for printing out the 3 nodes' values. After calling delete and trying to delete node3, it still prints out the 3 nodes. I'm not sure where I've gone wrong. I find the node preceding the one I want to delete and set its next pointer to the node after the node after (informally: node.next = node.next.next).

Any ideas?

Thanks for the help, bclayman

4
(1) yes, pointer to something means you need the address of something. (2) your delete function doesn't do anything: current = current->next->next; only changes a local variable. - lurker

4 Answers

7
votes
but xCode wanted me to add "&" in front of "node3". Is it generally true that
when I define a function to take a pointer, I need to pass in the memory 
address?

yes, if you declare the function to take a pointer, you must pass it a pointer.

Also when deleting a value from a linked list you are going to want to change

current->next = current->next->next
6
votes

You should be passing it &node3. For deleting, please change your code from current = current->next->next; to current->next = current->next->next;

4
votes

Is it generally true that when I define a function to take a pointer, I need to pass in the memory address?

Yes, xCode is right. node3 is a struct node, but your function delete is taking struct node * as second parameter, so you have to pass the pointer to node3, not the variable itself.

After calling delete and trying to delete node3, it still prints out the 3 nodes.

It because you're not changing the value of next. Also, to be memory-safe, don't forget to check if the pointer is NULL:

while ((current->next != toDelete) && (current->next != NULL)) {
    current = current->next;
}
if (current->next != NULL)
    current->next = current->next->next;
4
votes

Just try changing current = current->next->next; to current->next=current->next->next. Let me know if it doesn't work.