Home > Mobile >  How to properly allocate memory for linked list in C inside function?
How to properly allocate memory for linked list in C inside function?

Time:11-23

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.

  • Related