Here is the code to create a link in the list which i read off the internet to try understand linked lists in c:
//insert link at first location
void insertFirst(int key, int data) {
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
//point it to old first node
link->next = head;
//point first to new first node
head = link;
}
I am really not understanding how the following line works as a whole:
struct node *link = (struct node*) malloc(sizeof(struct node));
and more specifically:
(struct node*)
because my understanding is that the asterisk must come before the pointer name and yet its at the end of the struct name. Please correct me if I'm wrong and please if you can, explain how this works?
Casting the return value of malloc is unnecessary.
As per standard 7.22.3.4
The malloc function returns either a null pointer or a pointer to the
allocated space.
You should check its return value to know whether it succeeded or not.
What malloc does?
The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
my understanding is that the asterisk must come before the pointer name and yet its at the end of the struct name
Here you are not dereferencing anything. Rather you are typecasting. (which is again I would repeat that unnecessary).
struct node* here is a type of the pointer variable. Same way int or double is a type, this is also a type.
Assume you have to create database of a students having some entities.
struct node
{
int id;
char name [100];
};
Next thing,
struct node *link = (struct node*) malloc(sizeof(struct node));
How above line works ? you need to create one node or memory, So how will you create it, use malloc(). Next things how much memory you are going to create , equal to total size of your data members of structure, so for that its using
struct node *link = malloc(sizeof(struct node));
here link is nothing but name of dynamic memory we created to put some data into that. once memory is created put some data into memory.
scanf("%d %s\n",&link->id,link->name);
similarly you can do above task no of times.
typecasting is not compulsory or not advised to do. So below statement is correct.
struct node *link = malloc(sizeof(struct node));
In order to create a linked list you have to allocate the units -in your case :
struct node
so either you pre-allocate the memory for the list or dynamically allocate them every time you add a node to the list, the memoery for the node has to be recruited from somewhere, in this case - malloc does that.
Hope that helps
Related
In creating a linked list we make a node structure and it consists of both data and a pointer to the next node. Later when we make a function to append elements onto the linked list, we make a temporary node to store the inputted data.
Let’s consider the following program-
#include<stdio.h>
struct node
{
int data;
struct node* link;
}
struct node* root=NULL;
void main(append)
{
struct node* temp;
temp= (struct node*)malloc(sizeof(struct node))
.....
}
My first question set:
In line 11, why do we need to mention (struct node*) before the malloc function?
What is the significance of that?
My second question set:
If we are making a doubly linked list which would have a node structure consisting of 2 pointers (for next and previous node), would we also initialize a pointer (for traversing the list) of the struct node type?
Is there a different way to initialize the pointer in that case?
The significance is to make bugs in your program,
The malloc will return void* and when you assign to your struct somthing* it will convert automaticlly.
You simply don't cast the result of malloc as it returns void* . There is one fine explanation here
A better solution might be :
struct node *temp;
temp = malloc(sizeof *temp);
why do we need to mention '(struct node*)' before the malloc function,
what is the significance of that?
By writing (struct node*) before the malloc function, you are type-casting the return value to the specified type. The cast here is optional and often frowned upon.
if we are making a doubly linked list which would have a node
structure consisting of 2 pointers(...
When making a doubly linked list, you should declare something like:
struct node {
int data;
struct node *next;
struct node *previous;
};
You can allocate space for a node by using the malloc function. The next and previous pointers are again pointers to struct nodes. Call malloc again to allocate space for the next element. For the first node, the previous should be NULL and for the last node, next should be NULL. Here is one implementation.
This is the because the return type of malloc is void*. (struct node*) is a cast using which you tell the compiler that you want to treat the value returned by malloc as a pointer to struct node.
For double linked list you can use,
struct node
{
int data;
struct node *next,*prev;
};
int main()
{
struct node *new_node=(struct node *)malloc(sizeof(node));
}
malloc returns the void pointer(can be checked and verified at the header ), and so the type casting is necessary while assigning it to the other type of variable.
Request you to read at the link https://www.tutorialspoint.com/cprogramming/c_type_casting.htm
I'm studying linked lists from this article.
The writer of the tutorial never creates actual nodes, but only pointer variables of type node, as you can see with the following code...
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
and then he allocates space for them in the heap...
head = (struct node*)malloc(sizeof(struct node));
second = (struct node*)malloc(sizeof(struct node));
third = (struct node*)malloc(sizeof(struct node));
why doesn't he ever create actual nodes? code for which should look something like this...
struct node head;
struct node second;
struct node third;
If my knowledge is right (correct me if I'm wrong). Simply declaring the pointer variable doesn't create the actual variable(node in case of linked lists), and hence cannot be dereferenced like the writer of the tutorial in the article using the code
head->data = 1;
I mean, if that works, then why doesn't this work?
int *a;
a=5;
printf("%d",*a);
Obviously, the above code doesn't output 5.
Which means that another variable needs to be created, and then it needs to be stated that the address of the variable is stored in a pointer variable, only then it can be dereferenced...like the following code...
int *a;
int b=5;
a=&b;
printf("%d",*a);
This outputs 5.
So how does the author gets away with not creating the nodes? He simply creates the pointer variables and then simply dereferences them....
The nodes are in the heap, that's what malloc is for.
To use code without linked list to explain, it's similar to:
int *a = NULL;
a = malloc(sizeof(int));
*a = 5;
printf("%d",*a);
The structure pointers are created so that they can refer to address.Since normal structure variables can't store the address, this syntax is wrong.
struct node head;
struct node second;
struct node third;
I am trying to dynamically allocate list of pointers to pointers of structs which each contain a list of structs with the following definition:
struct node {
char *text;
struct node *next; };
I am also using a typedef:
typedef struct node Node;
I am creating a list of nodes to hold each list by declaring the following:
Node **list;
list = (struct node**) malloc(sizeof(struct node*) * arraySize);
At each of the nodes of list I will have another list which I am creating as follows:
list[i] = malloc(sizeof(struct node*) * subArraySize);
I have several questions:
Is this the correct implementation for such a problem?
How can I access the text data member of the first node of each list within the larger list?
If my question is vague please let me know. My confusion on this topic makes it difficult to word my question properly.
Assuming your memory is allocated and filled up correctly, you'd access the text data member of the first node of each node* array within the larger node** array via:
list[i]->text
But, to answer your question about the implementation being correct, it's not really. You'd probably be happier doing this:
struct node **list;
list = (struct node**) calloc(sizeof(struct node*) * arraySize);
for (int i=0; i<arraySize; ++i) {
list[i] = (struct node*) malloc(sizeof(struct node));
list[i]->text = ""; // or whatever you want to start with
list[i]->next = NULL;
}
This creates a node** array (called list, since you wanted to call it that, but I would call it something else indicates it's an array of node-based linked lists), then instantiates a block of memory for each head node so that list is full of valid node*s and you can start working with them.
When you go to append something to each of your linked lists, you'd do something like this (this appends to the end, it's up to you to implement insertion based on comparing values if you want sorted data, etc.):
int i = index_where_you_want_to_insert;
struct node *currNode = list[i];
struct node *newNode = (struct node*) malloc(sizeof(struct node));
newNode->text = ""; // or whatever you want to start with
newNode->next = NULL;
while(currNode->next != NULL) {
currNode = currNode->next;
}
currNode->next = newNode;
It may also help you to see this question about using typedef with linked lists.
If I've made any syntactic or semantic errors in my code, I apologize, it's been a while since I wrote C and I may be rusty with how to refer to structs. I welcome corrections.
As part of an assignment that is now past due, I was to read a list of search terms from a text file and store these in memory for searching. I decided to use a linked list to store the terms and my implemenation of struct node (stored in myheader.h) looks like this:
struct Node{
char * term;
int termLength;
struct Node *next;};
To save the rootNode as the head of my list, I had a separate function for creating it called startList that is defined as such:
struct Node * startList(char * sterm){
struct Node * rootNode;
rootNode=(struct Node *)malloc(sizeof(struct Node));
assert(rootNode != NULL);
memset(rootNode,0,sizeof(struct Node));
rootNode->term=sterm;
rootNode->termLength = strlen(sterm);
rootNode->next=NULL;
return rootNode;
}
This seems to work fine, the trouble arises when I try to add a new node onto this rootNode, which is supposed to be done with this function:
void insert_another_node( struct Node * headNode, char * sterm){
struct Node * newNode = (struct Node *) malloc(sizeof(struct Node));
newNode->term=sterm;
newNode->next=NULL;
newNode->termLength=strlen(sterm);
while (headNode->next != NULL){
headNode=headNode->next;}
headNode->next=newNode;
}
These functions are all called in this for loop:
while ((fgets(search_wrd,41,list)) != NULL){
strtok(search_wrd, "\n");
if (count==0){
rootNode=startList(search_wrd);}
else{
insert_another_node(rootNode,search_wrd);}
count++;
}
fclose(list);
}
Say I am trying to store a list of planets in this list, the last planet being Neptune. The insert_another_node function will update the terms stored in ALL of the nodes to the most recent term (including the rootNode). The result is the right number of nodes, but they all store "Neptune" at someNode->term.
All of the insert to the end of a linked list implementations I've seen for a linked list in c follow my logic, so I can't understand how this weird update is happening let alone a way to fix it. Any help would be greatly appreciated!
You are just assigning sterm each time, all the assignments point to the same original buffer. You need to make a copy each time.
Use strdup like this:
rootNode->term=strdup(sterm)
and
newNode->term= strdup(sterm);
You need to allocate new memory for each sterm. If you reuse the same memory location they will all have the same value and if you change one you will change them all (because they are the same).
I have a two struct, one is linked list.
typedef struct Mark{
int people;
Node *nodeyy;
}Mark
typedef struct Node{
struct node next;
int value;
}Node
if i allocated memory for a node, let say
Node *node1=malloc( sizeof(struct Node));
And I also allocated memory for a bookmark, let say
Mark *mark1=malloc( sizeof(struct Mark));
I want to make the pointer nodeyy in the mark1 points to the same thing as node1, how can i do that?
I think that
mark1->nodeyy=node1;
is definitely wrong.
change the int* in struct Mark to Node*
typedef struct Mark{
int people;
Node *nodeyy;
}Mark
then you can do
mark -> nodeyy = (Node *) malloc(sizeof(Node))
its correct now:
You will have to initialize the pointer or point it to an existing variable that you know won't go out-of-scope. BUT since node1 is dynamically allocated, you're just assigning one pointer to another, this creates a sort of reference to the newly allocated memory pointed by node1.
mark1->nodeyy = node1;
After this statement, mark1->nodeyy and node1 point to the memory location returned by the malloc(sizeof(Node)).