Не уверен, почему я получаю ошибку сегментации здесь - PullRequest
2 голосов
/ 16 июня 2019

Я знаю, что могу изменить код, чтобы исправить ошибку, но я не понимаю, почему я получаю ошибку сегментации.Спасибо за помощь, спасибо.

typedef struct nodes{
    int data;
    struct nodes *next;
} node;

int main(int argc, char * argv[]){
    node *head = NULL;
    node *tmp = NULL;
    int i;

    head = malloc(sizeof(node));
    tmp = head;
    for(i = 0; i < 10; i++){
        tmp->data = i;
        tmp->next = malloc(sizeof(node));
        tmp = tmp->next;
    }
    tmp = NULL;
    for(tmp=head; tmp->next != NULL; tmp = tmp->next){
        printf("%d\n", tmp->data);
    }

}

Это вывод:

0
1
2
3
4
5
6
7
8
9
0
Segmentation fault: 11

Ответы [ 2 ]

3 голосов
/ 16 июня 2019

Указатель next последнего узла не установлен на null. Таким образом, условие tmp->next != NULL во втором for -цикле никогда не будет выполнено. Действительно, вы можете видеть, что некоторое число мусора (0) печатается после последнего номера (9), до того, как возникнет ошибка сегмента.

Когда вы делаете это:

tmp->next = malloc(sizeof(node));

Вы также должны добавить что-то вроде этого:

tmp->next->next = NULL;

Таким образом, вы инициализируете каждый узел «безопасно», указав для next значение NULL. Все, кроме последнего узла, получат правильное значение на следующей итерации.

РЕДАКТИРОВАТЬ , как указано @Someprogrammerdude в комментарии, в конце вы получите один дополнительный узел, даже если вы сделаете то, что предложено выше. Чтобы это исправить, вы можете изменить цикл создания следующим образом:

for(i = 0; i < 10; i++){
    tmp->data = i;
    if (i < 9) {
        tmp->next = malloc(sizeof(node));
    } else {
        tmp->next = NULL;
    }
    tmp = tmp->next;
}
2 голосов
/ 16 июня 2019

Вы получите немного более чистый код, построив список в обратном порядке.Другими словами, начните с добавления последнего узла в список, а затем вставьте дополнительные узлы в начало списка.Код выглядит следующим образом:

node *head = NULL;
for (int i = 9; i >= 0; i--)
{
    node *tmp = malloc(sizeof(node));
    tmp->data = i;
    tmp->next = head;
    head = tmp;
}

Обратите внимание, что поскольку head изначально NULL, последний узел в списке будет иметь указатель next, установленный на NULL.Вот чего не хватало в вашем коде.

...