Reputation: 65
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;
}
Upvotes: 5
Views: 22328
Reputation: 9680
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;
}
Upvotes: 0
Reputation: 2373
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
Upvotes: 4
Reputation: 1433
This:
typedef struct list{
struct NODE* head;
}LIST;
Should be this:
typedef struct list{
NODE* head;
}LIST;
Tested and compiles fine with that change.
Upvotes: 3
Reputation: 141648
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).
Upvotes: 2