Question

I am new to programming. I am trying to learn C and pointers, but it is giving me much trouble. I got the following error trying to implement a singly linked list. I searched online, and I couldn't find someone who had an error just like mine, or perhaps I just didn't couldn't make sense of it with my problem.

The following is the error I received:

warning: incompatible pointer types initializing 'NODE *' (aka 'struct node *') with an expression of type 'struct NODE ' [-Wincompatible-pointer-types] NODE temp = (*l)->head;

    NODE* temp = (*l)->head;

In main, I passed the address of the variable of type LIST. So, I thought I had to dereference 'l', to get the address of where the LIST type is located, then I had to dereference with an arrow to get the address of where the NODE is located. Where am I confused? I do appreciate the help.

Below you will see the code I have written:

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

typedef struct list{
    struct NODE* head;
}LIST;

void insert(LIST** l, int x){

    if((*l)->head == NULL){

      NODE* new_Node = (NODE*) malloc(sizeof(NODE));
      new_Node->next = NULL;
      new_Node->value = x;
    }

    NODE* temp = (*l)->head;

    while(temp->next != NULL){
      temp=temp->next;
    }

    NODE* new_Node = (NODE*) malloc (sizeof(NODE));
    temp->next = new_Node;
    new_Node->next = NULL;
    new_Node->value = x;
}

int main(){

    LIST *l = (LIST*) malloc(sizeof(LIST));

    insert(&l, 5);

    return 0;
}
Was it helpful?

Solution

I guess your problem is here :

typedef struct list
{
     struct NODE* head;
}LIST;

just remove struct keyword before NODE

typedef struct list
{
     NODE* head;
}LIST;

or

typedef struct list
{
     struct node* head;
}LIST; 

Also you need to initialize the head with NULL to make this condition to wwork

  if((*l)->head == NULL) .....

so when you create your list add l->head = NULL;

      LIST *l = malloc(sizeof(LIST));
      l->head = NULL;

And the last one (i hope) when you create your first node, you forget to assign head to it, and return in order not to add the first element twice

      if((*l)->head == NULL)
      {

         NODE* new_Node = malloc(sizeof(NODE));
         new_Node->next = NULL;
         new_Node->value = x;
         (*l)->head = new_Node;
         return;
      }

And BTW, don't cast malloc results in C

OTHER TIPS

This:

typedef struct list{
    struct NODE* head;
}LIST;

Should be this:

typedef struct list{
    NODE* head;
}LIST;

Tested and compiles fine with that change.

Your use of *l is correct. The problem is with the line:

NODE* temp = (*l)->head;

The left-hand side is NODE *, which is the same as struct node *, however the right-hand side is struct NODE *.

C is case-sensitive, struct node and struct NODE are different types. Also, the namespace of struct tags is separate to that of other types, so NODE and struct NODE are also different types.

I think you meant, in LIST's definition, that struct NODE* head; should be NODE* head;. There is no warning generated on that line, because in C it's legal to implicitly declare a struct type just by mentioning it (i.e. this line declares the new type struct NODE also).

There is code repetition in your insert function. You should not use the struct keyword before NODE in the second typedef statement because NODE is already an alias for the type struct node. That's why you are getting the warning mentioned in your question. Also, you should not cast the result of malloc. Please read this - Do I cast the result of malloc? I suggest the following changes to your code.

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

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

typedef struct list {
    NODE *head;
} LIST;

void insert(LIST **l, int x) {
    // do not cast the result of malloc.
    // also, do not repeat the type on the rhs.
    // create the new node to be inserted

    NODE *new_Node = malloc(sizeof(*new_Node));
    new_Node->next = NULL;
    new_Node->value = x;

    NODE *temp = (*l)->head;

    // check if the head of the list is empty
    // if yes, simply assign the new node to head
    // and return
    if(temp == NULL) {
        (*l)->head = new_Node;
        return;
    }

    // reach the last node in the list
    while(temp->next != NULL)
        temp = temp->next;

    // insert the new node to the end of the list
    temp->next = new_Node;
}

int main(void) {
    LIST *l = malloc(sizeof(*l));
    insert(&l, 5);
    insert(&l, 10);

    // print the value of the head node
    printf("%d\n", l->head->value);

    // print the value of the next node
    printf("%d\n", l->head->next->value);

    NODE *head = l->head;
    NODE *temp = NULL;

    // free the nodes in the list
    while(head != NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }

    // free the pointer to the 
    // head of the list
    free(l);
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top