Указатели и связанный список в C | Сбой на дисплее - PullRequest
0 голосов
/ 02 мая 2018

При запуске display () происходит сбой программы. Может быть, проблема в create (). Я пытался, но я не могу определить проблему. Я уничтожаю их ссылки, но где? я не знаю. Это односвязный список.

структура узла

typedef struct node{
   int data;
   struct node *right;
}list;

Вот создание ()

void create(list *start){
int data;
    printf("Input value : ");
    scanf("%d",&data);
    if(data==0){
        start=NULL;
        return;
    }
    else{
        start=(list*)malloc(sizeof(list));
        start->data=data;
        create(start->right);
    }
}

А дисплей () равен

void display(list *start){
    printf("%d",start->data);
    if(start->right==NULL)return;
    display(start->right);
}

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Проблема здесь в том, что create() выделяет новые узлы, но теряет указатели на них, это прекрасный пример утечки памяти.

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

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

Так как же изменить указатель, который вы передали в функцию изнутри функции? Это просто - просто передайте в функцию адрес указателя. Когда вы хотите изменить какую-либо переменную, вы указываете указатель на ее адрес, а затем разыменовываете указатель. Здесь вы будете делать то же самое - взять адрес указателя и разыменовать двойной указатель, который указывает на него. Нужны только небольшие изменения, такие как:

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
    int data;
    struct node *right;
}list;

void create(list **start){
    int data;
        printf("Input value : ");
        scanf("%d",&data);
        if(data==0){
            start=NULL;
            return;
        }
        else{
            *start=(list*)malloc(sizeof(list));
            (*start)->data=data;
            create(&(*start)->right);
        }
}

void display(list *start){
    printf("%d",start->data);
    if(start->right==NULL)return;
    display(start->right);
}


int main(void){
    list *LIST=NULL;

    create(&LIST);
    display(LIST);
    return 0;
}
0 голосов
/ 02 мая 2018

Во-первых, в create() функция start должна иметь тип list**, если вы хотите, чтобы изменения вызывали изменения при вызове функции main(), в противном случае это просто вызов по значению.

void create(list **start) {
  /*some code */
}

Во-вторых, ваша рекурсивная логика связывания узла верна, так как каждый раз start указывает на новую ячейку памяти и каждый раз, когда старая память теряется, поэтому связь между узлами отсутствует.

Итак, возьмите дополнительную temp переменную-указатель типа list. create() функция выглядит как

void create(list **start,list *new){
        int data;
        printf("Input value : ");
        scanf("%d",&data);
        if(data != 0){
                new = malloc(sizeof(list));/*allocate memory */
                new->data = data;/*put the data */
                new->right  = *start; /*new node right should be head ptr */
                *(start) = new; /*update the head ptr */
                create(start,new);
        }
        else
                return;
}

А с main() назовите create() вот так

int main(void) {
        list *head_ptr = NULL, *temp = NULL;
        create(&head_ptr,temp);
        display(head_ptr);
        return 0;
}
...