Two structs for a linked list in C - c

Ok I am creating an ADT for a singly linked list. I have a Struct name List that stores the pointer to the first node(first item in the list, which is also a struct)and size. The node stores first name and a pointer to the next node. Here are the sturcts:
typedef struct List *ListP;
struct List{
ListP head;
int size;
};
struct node{
char name[20];
nodeP next;
};
First I called malloc to give me memory for struct List:
ListP newList;
newList = malloc(sizeof(struct List)); //should I typecast this to (ListP *)?
if (newList == NULL){
fprintf(stderr, "Memory allocation failed");
}
else{
newList->head = NULL;
newList->size = 0;
}
Then I called malloc again to give me memory for the first node:
struct node *new;
newNode = malloc(sizeof(struct node));
if (newNode == NULL){
fprintf(stderr, "Memory allocation failed");
}
else{
newNode->name = 'Jay';
newNode->next = NULL;
Now that I have my List and a new node, I assigned list->head to the address of the new node;
newList->head = newNode;
Untill this time the compiler doesn't complain. But when I try to access the elements in the first node using the pointer that I have for the list:
name = newList->head->name;
The compiler complains that struct List has no member named 'name'
How can I access the field in struct node, assuming that I only have pointer to the struct List and List->head is pointing to the first node.
Any help would be appreciated.

You declared head as a ListP when it should be of type NodeP assuming that NodeP is a node*.
Try being consistent with names. Here is a suggested revision:
// forward declarations
struct List;
struct Node;
typedef struct List *ListP;
typedef struct Node *NodeP;
struct Node{
char name[20];
NodeP next;
};
struct List{
NodeP head;
int size;
};

Related

How to handle the root of a Singly-Linked List

Let's say I have a node in a Linked List defined as follows:
struct movie {
char title[50];
int year;
};
// so we can swap in other types by changing the `typedef Item`
typedef struct movie Item;
struct node {
Item item;
struct node *next;
};
How is the head/root of the list usually handled? Is this as simple as just doing:
struct node *head;
Or is the LinkedList usually handled as a wrapper struct, something like:
struct LinkedList_ {
struct node* head;
size_t size;
// anything else?
} LinkedList;
And we just use the LinkedList and add functions around that item? For example: LinkedList->addNode(...).
There really is no right and wrong here. This is more of a design decision, than anything else. For me personaly, I usually don't use any kind of wrapper, nor do I store the size, since the end of the list is marked by a null pointer. So to iterate it I usually use something like this:
for(struct node *current = first; current != NULL; current = current->next);
I also store both the head and the tail. So You can easily add nodes to the list.
struct node *newNode = (struct node *)malloc(sizeof(struct node));
newNode->next = NULL;
tail->next = newNode;
tail = newNode;

What exactly the meaning of structure pointer

struct Node
{
int data;
struct Node* left, *right;
};
What exactly the meaning of this struct Node *? Is the function below returning a pointer to a Node?
struct Node* newNode(int data)
{
struct Node* node = new(struct Node);
node->data = data;
node->left = node->right = NULL;
return (node);
}
struct Node;
Is the name of your struct.
What exactly the meaning of this struct Node*?
struct Node* node;
You're declaring a pointer to the struct Node that needs to be allocated with some memory. There is no new keyword in C. You need to use malloc() to allocate the required bytes of memory. You can allocate that like this:
struct Node* node = (struct Node *)malloc(sizeof(struct Node));
Is it returning a pointer to a Node?
This line:
return (node);
Returns the type of struct Node* to the function.

assignment to incompatible pointer type double pointer

I am trying to add nodes right after the *add pointer in my linked list
my struct and code is as follows, but shows an error in (*add)->next = new_node:
typedef struct {
int data;
struct node* next;
}node;
void create_node(node **add,int dat)
{
if((*add) == NULL)
{
(*add) = (node*)malloc(sizeof(node));
(*add)->data = dat;
(*add)->next = NULL;
}
else
{
node *new_node = (node*)malloc(sizeof(node));
new_node->data = dat;
new_node->next = (*add)->next;
(*add)->next = new_node; //assignment to incompatible pointer type error
}
}
You're declaring next as a pointer to struct node, but there's no struct node in your code (only the typedef node).
You need to give a name for the struct in order to refer to it in the declaration of next:
typedef struct node {
Currently struct node refers to a different, unrelated struct (that you haven't defined).

Incompatible pointer type error using structs

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;
}
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
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;
}

Assignment from incompatible pointer type in C

I keep getting an "Assignment from incompatible pointer type" and I can't figure out why. I thought it looked right. I'm just trying to do the basics of a linked list in C.
typedef struct{
int id;
struct node *next;
} node;
node *root = NULL; // Sets up a root node when the program starts.
create nodes(int id){
if(root == NULL){
root = (node*)malloc(sizeof(node));
root-> id = -1;
node *nextNode;
nextNode = (node*)malloc(sizeof(node));
nextNode -> id = id;
root-> next = nextNode; // This line is throwing an error.
}
}
I feel like it's something simple but I can't put my finger on it...
Your struct is actually an unnamed struct typedef-d to node, but you're trying to refer to it as struct node later (which is not the same as your node typedef). Quick fix is to simply give the struct a name:
typedef struct node {
int id;
struct node *next;
} node;
Or, if you prefer (and this is completely stylistic), remove the typedef and correct your other references to the struct:
struct node {
int id;
struct node *next;
};
struct node *root = NULL;
create nodes(int id){
if(root == NULL){
root = malloc(sizeof(struct node));
root->id = -1;
struct node *nextNode;
nextNode = malloc(sizeof(struct node));
nextNode->id = id;
root->next = nextNode;
}
}
Four points here:
First. Add a name of the struct node, if you must include pointer in the field of the struct (as #JamesMcLaughlin pointed out above). For example:
typedef struct nodetag {
int id;
struct nodetag *next;
} node;
Second. Make sure you are using the variable type create as intended. I assume user-defined variable type create exist within your #define or somewhere else. If not, this will cause a compiler error. Even if you did, this won't compile as you don't have a return statement that returns create.
Third. Include node *root = NULL; within your function nodes. Otherwise, function nodes won't recognize the variable root and results in a compiler error.
Fourth. Declare local variables in the beginning of the function. The line struct node *nextNode; will cause a compiler error for C89 as C89 does not allow type-declaration after statements. C99, however, allows such practice. It's advised to declare all of the local variables in the beginning of the function to be compatible with both C89 and C99.
Try this
struct node{
int id;
struct node *next;
} ;
struct node *root = NULL; // Sets up a root node when the program starts.
/* Return type is missing in your code*/ create_nodes(int id){
if(root == NULL){
root = (struct node*)malloc(sizeof(struct node));
root-> id = -1;
struct node *nextNode;
nextNode = (struct node*)malloc(sizeof(struct node));
nextNode -> id = id;
root-> next = nextNode; // This line is throwing an error.
}
}

Resources