0

I am newbie in C and I am trying to write a linked list in which each node simply contains an int. The definition of the structure is ok, but I also want to write methods to update this linked list (add element at the tail and delete the head element). (I want to be able to read the most recently added element)

I wrote the functions below, but I don't know where the free should take place and how to implement it. Could anyone help me with this?

typedef struct Node{
    Node next = NULL;
    int number;
} Node;

void add_node(Node *LL,int val){ 
    // add node to the end of the linked list
    new_node = (struct Node *)malloc(1*sizeof(struct Node));
    new_node->number = val;
    Node n = *LL;
    while (n.next != NULL){
        n = n.next;
    }
    n.next = new_node;
}

void delete_head(Node *LL){
     // update the head
    *LL = LL->next;
    //free?
}

void update_LL(*LL,int val){
    add_node(*LL,val);
    delete_head(*LL);
}
AeroX
  • 3,387
  • 2
  • 25
  • 39
teaLeef
  • 1,879
  • 2
  • 16
  • 26
  • 1
    `Node next = NULL;` --> `struct Node *next;` in C. – BLUEPIXY Oct 07 '14 at 15:57
  • 1
    As written, there is no way to update the head from within `delete_head`: it is passed a pointer to the head node, but has no idea where that value is stored, and thus cannot update it. You can (as many have explained) delete that node, but whatever is keeping track of the head needs to be updated to the new head. – Scott Hunter Oct 07 '14 at 16:06

4 Answers4

1

I rename your data structure this way:

struct pointer
            {
            int field; 

            struct pointer *link; 
            };
typedef struct pointer cell;  

Then we can use this function for your need:

void ad_an_element_at_the_end_of_the_list()
         {
         cell *p=NULL;
         cell *ptr=head;

         int value;

         cout<<" Integer number to insert at the end of the list: ";
         cin>>value;
         p=(cell*)malloc(sizeof(cell));
         p->field=value;
         p->link=NULL;
         if(ptr==NULL) 
            {
            ptr=p;
            head=ptr;

            }else
                {
                if(ptr->link==NULL)  t
                  {
                  ptr->link=p;
                  head=ptr;

                  }else
                     {
                      while(ptr->link!=NULL) 
                        {
                        ptr=ptr->link;
                        }
                     ptr->link=p;

                    }
            }
    }
0

Try changing *LL = LL->next; for Node *nextNode = LL->next;. Then you can call free(LL) followed by LL = nextNode.

void delete_head(Node *LL){
    Node *nextNode = LL->next;
    free(LL);
    LL = nextNode;
}

This then frees the Node at the head and moves the pointer to the next one in the Linked List.

AeroX
  • 3,387
  • 2
  • 25
  • 39
  • 3
    Since `LL` is effectively a local variable, this will *not* move the head. – Scott Hunter Oct 07 '14 at 16:00
  • @ScottHunter It's been a while since I've used C but would this be solved by passing a reference (using the `&` symbol before the variable, when passing it to the function)? – AeroX Oct 07 '14 at 16:08
  • 1
    I think you should review how "passing by reference" and "passing by value" is done. If a pointer is passed as an argument it points to a memory location, whatever operations are performed on that memory location by whomever function in whichever scope are permanent. – Murtaza Zaidi Oct 07 '14 at 16:09
  • @MurtazaZaidi ^ This was my original understanding – AeroX Oct 07 '14 at 16:11
  • 2
    @AeroX: No; then you'd be passing a pointer-to-a-pointer-to-a-Node, and have a type mismatch. But if `LL` were declared as `Node **LL`, and the code referred to `*LL` for the pointer to the `Node`, then that would work. – Scott Hunter Oct 07 '14 at 16:12
0

Possibly a duplicate of this question LinkedList - How to free the memory allocated using malloc

Basically you have to store the pointer to the node you want to delete otherwise you will leak that memory as there will be no reference to that memory location anywhere in your code.

try this in your delete_head function:

Node *temp = LL;

*LL = LL->next;

free(LL);

Hope this helps!

Community
  • 1
  • 1
Jared Wadsworth
  • 839
  • 6
  • 15
0

You need to save your link to node which is next before you delete current node. Otherwise you won't be able to refer any node of your linkedlist. Now when you have backed up your link to next node, you can free current node pointed by LL, and then assign LL pointer to next node which you had earlier backed up in temp pointer.

Node *temp = LL->next;
free(LL);
LL = temp;
Murtaza Zaidi
  • 599
  • 3
  • 14
  • Since `LL` is effectively a local variable, this will *not* move the head. – Scott Hunter Oct 07 '14 at 16:08
  • @ScottHunter please review this http://www.nongnu.org/c-prog-book/online/x641.html – Murtaza Zaidi Oct 07 '14 at 16:10
  • If a pointer is passed as an argument it points to a memory location, whatever operations are performed on that memory location by whomever function in whichever scope are permanent. – Murtaza Zaidi Oct 07 '14 at 16:11
  • But the pointer being passed points to a Node, so you can make changes to that Node, but not the original variable pointing to it (which is what head is). And to do *that*, you'd need to make an assignment to `*LL`; changes to `LL` from within this function have *no* effect outside of the function. – Scott Hunter Oct 07 '14 at 16:15
  • I think you need to review your knowledge of pointers. If p is a pointer, it points to some memory location, we use p to make changes in that memory location directly. Now that change is permanent. If I free that memory location all data which was stored there is now lost, if I update value at that location, new value would be permanent, not specific to scope of function. – Murtaza Zaidi Oct 07 '14 at 16:21
  • Pointers and Variables are two different things. Changes made to variables are dependent on scope in which those changes were made. Any change made via pointer is persistent in all scopes. – Murtaza Zaidi Oct 07 '14 at 16:22
  • So if the call was `delete_head(&x)`, where `x` is declared as a `Node`, what exactly would `LL = temp` within the function change? – Scott Hunter Oct 07 '14 at 17:20
  • x is pointer to node, we pass address of this pointer to LL, now LL is pointing to same node which x was pointing. You get it? – Murtaza Zaidi Oct 07 '14 at 17:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/62619/discussion-between-scott-hunter-and-murtaza-zaidi). – Scott Hunter Oct 07 '14 at 17:23