I have spent several hours trying to initialize linked list with, say, integer values from 0 to 10. I create pointer of struct node and pass its reference to function init_ll. The init_ll function should initialize 10 elements of linked list. But it seems only first memory allocation works, because I get liked list with only one element.
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct node {
int value;
struct node *next;
} node_t;
void init_ll(node_t **head, int n)
{
// allocate memory for the first node
node_t *p= (node_t *)malloc(sizeof(node_t));
// copy the address of the first node to head
*head = p;
// initialize first node value
p->value = 0;
p = p->next;
// initialize the reamining nodes
for (int i=1; i<n; i ) {
p = (node_t *)malloc(sizeof(node_t));
p->value = i;
p= p->next;
}
p = NULL;
}
int main(void)
{
node_t *head;
init_ll(&head, 10);
return 0;
}
It seems I misunderstand some conception about memory-scope. I will be grateful if someone provide a proper example of allocation memory for linked list inside function. All I have found so far were examples of allocation of memory in main function.
CodePudding user response:
For starters it would be more correctly and clear to write in main
node_t *head = NULL;
Within the function you are not initializing data members next
of created nodes. They have indeterminate values. So this statement
p = p->next;
does not make sense. And moreover the pointer p
is overwritten in the for loop
p = (node_t *)malloc(sizeof(node_t));
Also pay attention to that you are changing the local variable (pointer) p
that is not linked with the list.
And the behavior pf the function will be incorrect if the user will pass a negative value as the second argument.
The function can be declared and defined the following way
size_t init_ll( node_t **head, size_t n )
{
while ( *head )
{
node_t *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
size_t cnt = 0;
for ( int success = 1; success && cnt < n; cnt )
{
*head = malloc( sizeof( node_t ) );
if ( ( success = *head != NULL ) )
{
( *head )->value = cnt;
( *head )->next = NULL;
head = &( *head )->next;
}
}
return cnt;
}
This while loop
while ( *head )
{
node_t *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
you could form as a separate function. For example
void clear( node_t **head )
{
while ( *head )
{
node_t *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
}
In this case the original function will look like
size_t init_ll( node_t **head, size_t n )
{
clear( head );
size_t cnt = 0;
for ( int success = 1; success && cnt < n; cnt )
{
*head = malloc( sizeof( node_t ) );
if ( ( success = *head != NULL ) )
{
( *head )->value = cnt;
( *head )->next = NULL;
head = &( *head )->next;
}
}
return cnt;
}
Also the defined macro name N
#define N 10
is not used in your program. So its presence in the program is unclear and it seems does not make sense.