Home > Enterprise >  How should I initialize linked list in C ?
How should I initialize linked list in C ?

Time:02-25

I have an array which I have to initialize into a list What I try to do

#include <stdio.h>
#include <string.h>

struct data_t 
{
    unsigned int id_;
    char name_ [50];
};

struct node_t
{
    node_t * next_;
    data_t data_;
};

void initialize(node_t **, const char **, const unsigned int);

int main()
{
    node_t * first = NULL;
    const char * data [3] = {"Alpha", "Bravo", "Charlie"};

    initialize(&first, data, 3);

    return 0;
}

void initialize(node_t ** head, const char ** data, const unsigned int n) {
    node_t * current = NULL;
    node_t * previous = NULL;
    for (size_t i = 0; i < n; i  )
    {
        current = new node_t;
        current->next_ = previous;
        current->data_.id_ = i 1;
        strcpy(current->data_.name_, data[i]);

        if (i == 1)
        {
            *head = previous;
            previous->next_ = current;
        } else {
            previous = current;
        }     
    }
};

next_ just loops and changes between 2 values. I tried many different options but nothing works. Please help. Why is this happening?

CodePudding user response:

You need to do something special in the case of 'first' vs 'not first', you knew this but had it wrong.

  • On the first one (i==0) you need to set head so the caller gets the pointer to the first node
  • on subsequent ones you have to set the prior ones next pointer to point at current. For the first one there is no prior

Plus you set the current->next to point to previous, thats wrong too, that made your loop

So this is what you need

for (size_t i = 0; i < n; i  )
{
    current = new node_t;
    current->next_ = NULL; <<<======
    current->data_.id_ = i   1;
    strcpy(current->data_.name_, data[i]);
    if (i == 0)
        *head = current;
    else
        previous->next_ = current;
    previous = current;
   
}

CodePudding user response:

Since you can't use std::strings, I suggest that you add a constructor to data_t that can copy the char array:

struct data_t {
    data_t(unsigned id, const char* name) :
        id_{id} // can be copied automatically
    {
        // the char array needs to be copied manually:
        std::strncpy(name_, name, sizeof name_ - 1);
        name_[sizeof name_ - 1] = '\0';
    }

    unsigned int id_;
    char name_[50];
};

With that, your initialize function could be simplified to

// last in `data`, first in the list:
void initialize(node_t*& head, const char** data, const unsigned int n) {
    for (unsigned int i = 0; i < n; i  ) {
        // create a new `node_t` with `next_` pointing at the current `head`
        // `data_` will be initialized by calling the added constructor
        // assign the returned `node_t` to `head`
        head = new node_t{head, {i   1, data[i]}};
    }
}

or

// first in `data`, first in the list:
void initialize(node_t*& head, const char** data, const unsigned int n) {
    for (unsigned int i = n; i > 0; --i) {
        head = new node_t{head, {i, data[i - 1]}};
    }
}

Note that initialize takes head by reference (&) to make calling it simpler:

int main() {
    node_t* first = nullptr;
    const char* data[3] = {"Alpha", "Bravo", "Charlie"};

    initialize(first, data, 3); // not &first here
}

Demo

  • Related