I am starting to grasp how Linked List work in C and I have a doubt about how to build a function that generate new elements for a linked list:
struct elem{
int data;
struct elem* next;
};
typedef struct elem* listEl; // we call data type pointer to an element listEl;
//how to create an element
listEl createElem1(){
listEl temp;
temp = malloc(sizeof(struct elem));
(*temp).data = 0;
(*temp).next = NULL;
return temp;
}
//how to create an element
listEl createElem2(){
listEl temp;
temp = malloc(sizeof(struct elem*)); ////
(*temp).data = 0;
(*temp).next = NULL;
return temp;
}
Here we have defined an element of a linked list as a structure with an integer and a pointer to another element of a linked list.
The other two functions are needed to generate new pointer to elements. Since we want to generate a new element, should we use to allocate the relevant memory for our element the function "malloc(sizeof(struct elem))"
while on the other hand the function malloc(sizeof(struct elem*));
would be an error, since we are allocating the size of a pointer and not the size of a struct?
I am asking this since in one of the lectures I am following about this topic a function to create new element has been defined in the second way and it seemed to me not correct.
Thanks in advance
CodePudding user response:
Your analysis is correct:
This is incorrect:
temp = malloc(sizeof(struct elem*));
Because it allocates space for a pointer to the struct, not the struct itself. Subsequently attempting to dereference temp
and read/write the fields will trigger undefined behavior because doing so would read or write past the end of allocated memory.
So this is correct:
temp = malloc(sizeof(struct elem));
Or better yet:
temp = malloc(sizeof *temp);
Because it doesn't depend on the name of the type of temp
.
CodePudding user response:
To create a new element of the list you need to create an object of the type
struct elem{
int data;
struct elem* next;
};
So you need to allocate dynamically a memory that will contain such an object. Thus you need to write
temp = malloc(sizeof(struct elem));
The function can be more safer if it will check whether a memory for an element of the list was successfully allocated. Also the function should accept the value that will be assigned to the created node of the list.
That is the function should be defined the following way
listEl createElem1( int data )
{
listEl temp = malloc( sizeof( *temp ) );
if ( temp != NULL )
{
temp->data = data;
temp->next = NULL;
}
return temp;
}
CodePudding user response:
The size of a pointer is not fixed since it just holds the value of the address (For example, the size of a char pointer on a 32-bit processor is 4 bytes, while the size of a char pointer on a 16-bit processor is 2 bytes).
The size of your struct will remain the same. If you're creating a new struct you can do something like:
struct elem *temp= malloc(sizeof(struct elem));
since it allocates the proper amount of memory