Новый узел не добавляется должным образом в конец связанного списка при добавлении через функцию - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь добавить новые узлы в связанный список через функцию добавления узлов.Но когда я печатаю список, кажется, что данные во всех узлах заменяются недавно добавленными данными.

typedef struct things {
    char *string;
    struct things *next;
} something;

void addnode(something **head, char *str);
void printlist(something **head);

int main()
{
    int i;
    char word[50];
    something *head = NULL;

    puts("How many strings?");
    scanf("%d", &i);

    while(i > 0)
    {
        scanf("%49s", word);
        addnode(&head, word);
        i--;
    }

    printlist(&head);
    return 0;
}

void addnode(something **head, char *str)
{
    something *last = *head;
    something *newnode;

    newnode = malloc(sizeof(something));
    newnode->string = malloc(50*sizeof(char));
    newnode->string = str;
    newnode->next = NULL;

    if ((*head)==NULL)
    {
        (*head) = newnode;
        return;
    }
    else
    {
        while(last->next != NULL)
        {
            last=last->next;
        }
        last->next = newnode;
        return;
    }
}
void printlist(something **head) //print contents of list, to check if list was created
{
    puts("print");
    something *current = *head;
    while(current != NULL)
    {
        printf("%s", current->string);
        current=current->next;
    }
}

Это то, что я придумал.Когда я ввожу, скажем, 5 слов one two three four five, я получаю вывод five five five five five.Это проблема с тем, как я пытаюсь печатать?Или это с тем, как я передаю указатели и связываю узлы?

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

Назначение указателей не копирует их содержимое.Просто заставляет их указывать на один и тот же адрес памяти.

В своем коде вы выделяете память для нового узла str и указываете его на адрес буфера (word для вашего случая).Делая это, в конечном итоге все узлы str будут указывать на содержимое адрес последнего значения буфера (пять для вашего случая).

newnode->string = malloc(50*sizeof(char));
newnode->string = str;

Другая проблема заключается в том, что вы не выделяете память динамически на основесодержимое буфера.

Чтобы выделить точно необходимый объем памяти, попробуйте следующее:

Замените:

newnode->string = malloc(50*sizeof(char));

На:

 newnode->string = malloc((strlen(str)+1)*sizeof(char));

На strlen вы получаете количество символов, а +1 - для выделения места для завершающего символа '\0'.

Итак, чтобы исправить вашу первоначальную проблему, вам необходимо скопировать содержимое буфера в недавно выделенную память:

Заменить:

newnode->string = str;

на

strcpy(newnode->string,str);
0 голосов
/ 04 декабря 2018

Изменить функцию вставки, например,

void addnode(something **head, char *str)
{
    something *last = *head;
    something *newnode;

    newnode = malloc(sizeof(something));
    newnode->string = malloc(50*sizeof(char));
    strcpy(newnode->string, str);
    newnode->next = NULL;

    if ((*head)==NULL)
    {
        (*head) = newnode;
        return;
    }
    else
    {
        while(last->next != NULL)
        {
            last=last->next;
        }
        last->next = newnode;
        return;
    }
}
0 голосов
/ 04 декабря 2018

В аддоне fuction () вместо

newnode->string = malloc(50*sizeof(char)); newnode->string = str;

try

newnode->string = strdup(str);

Должно работать.:)

...