Назначение NULL головному узлу в связанном списке в C - PullRequest
0 голосов
/ 15 января 2019

Пожалуйста, смотрите полный код ниже.

У меня есть начальный массив с именем arr. Я использую связанный список для хранения некоторых индексов с помощью функции append. После получения индексов я сохраняю их в связанном списке и использую clearList, чтобы изменить соответствующие значения на 0 (в этом примере arr [2] и arr [4]). Наконец, я освобождаю память, вызывая freeList, так как я закончил со связанным списком.

Однако, чтобы иметь возможность делать одно и то же снова и снова, мне нужно установить head в NULL всякий раз, когда я вызываю freeList. Но я не могу. Есть идеи, как это решить? Спасибо.

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

//Gurobi variables
GRBenv   *env = NULL;
GRBmodel *model = NULL;
//Gurobi variables

struct Node 
{ 
  int data; 
  struct Node *next;
  struct Node *end;
};

void append(struct Node** head_ref, int new_data) 
    { 
    struct Node *last = *head_ref;  
    struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));  
    new_node->data  = new_data; 
    new_node->next = NULL;
    new_node->end = new_node;
    if (*head_ref == NULL) 
    { 
       *head_ref = new_node;
       //printf("  ..Init Append %d\n",new_data);
       return; 
    } 
    last = (*head_ref)->end; 
    last->next = new_node;  
    (*head_ref)->end=new_node;
    //printf("  ..Append %d\n",new_data);
    return; 
} 

void clearList(struct Node *node, double *arr) 
    { 
    int i;
    if(node!=NULL)
        {
        struct Node tmp;
        tmp=*(node->end);
        while (node != NULL) 
            {  
            i=node->data;
            arr[i]=0;
            //printf("   ..clear %d \n", node->data,(node->end)->data);
            node = node->next; 
            }
        }
    }

void freeList(struct Node *node) 
    { 
    struct Node *tmp,*hd;
    hd=node;
    while (node != NULL) 
        { 
        tmp=node;
        node = node->next; 
        //printf("  ..Free %d \n", tmp->data);      
        free(tmp);
        } 
    hd=NULL;
    }

int main (){
    Node *head;     
    double *arr = (double *) malloc(sizeof(double) * 10);
    for(int i=0;i<10;i++)
        arr[i]=i;

    head=NULL;
    printf("Head:  %s\n", head);
    append(&head,2);
    append(&head,4);
    clearList(head,arr);
    for(int i=0;i<10;i++)
        printf("No %d : %.2f\n",i,arr[i]);
    freeList(head);

    free(arr);

    printf("%s", head);
    getchar();
    return 0;
    }

Ответы [ 3 ]

0 голосов
/ 15 января 2019

Вы уже меняете значение head в своей функции append, поэтому вам нужно сделать то же самое в freeList:

void freeList(struct Node **head_ref) 
    { 
    struct Node *tmp,*node;
    node=*head_ref;
    while (node != NULL) 
        { 
        tmp=node;
        node = node->next; 
        //printf("  ..Free %d \n", tmp->data);      
        free(tmp);
        } 
    *head_ref=NULL;
    }

int main (){
    /* do stuff */
    freeList(&head);
    /* do stuff */
    }
0 голосов
/ 16 января 2019

Просто для полноты: другим возможным вариантом будет использование макроса-оболочки для freeList().

void freeList(struct Node *node) 
{ 
    /* ... */
}

#define freeListNull(node) do { \
    freeList(node); \
    node = NULL; \
} while(0)

int main () {
    /* ... */
    freeListNull(head);
    /* ... */
}

Это решение имеет тот же недостаток, что и версия, которая возвращает измененный указатель. Вы можете просто забыть использовать правильный вызов freeListNull(head); и вместо этого позвонить freeList(head);. Наилучшим решением является функция freeList(), которая принимает адрес указателя head, как в ответе idk.

0 голосов
/ 15 января 2019

Я понял, что можно изменить функцию freeList, чтобы она возвращала значение NULL. Смотрите обновленный код ниже:

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

//Gurobi variables
GRBenv   *env = NULL;
GRBmodel *model = NULL;
//Gurobi variables

struct Node 
{ 
  int data; 
  struct Node *next;
  struct Node *end;
};

void append(struct Node** head_ref, int new_data) 
    { 
    struct Node *last = *head_ref;  
    struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));  
    new_node->data  = new_data; 
    new_node->next = NULL;
    new_node->end = new_node;
    if (*head_ref == NULL) 
    { 
       *head_ref = new_node;
       //printf("  ..Init Append %d\n",new_data);
       return; 
    } 
    last = (*head_ref)->end; 
    last->next = new_node;  
    (*head_ref)->end=new_node;
    //printf("  ..Append %d\n",new_data);
    return; 
} 

void clearList(struct Node *node, double *arr) 
    { 
    int i;
    if(node!=NULL)
        {
        struct Node tmp;
        tmp=*(node->end);
        while (node != NULL) 
            {  
            i=node->data;
            arr[i]=0;
            //printf("   ..clear %d \n", node->data,(node->end)->data);
            node = node->next; 
            }
        }
    }

Node* freeList(struct Node *node) 
    { 
    struct Node *tmp;
    while (node != NULL) 
        { 
        tmp=node;
        node = node->next; 
        printf("  ..Free %d \n", tmp->data);      
        free(tmp);
        } 
    return NULL;
    }

int main (){
    Node *head;     
    double *arr = (double *) malloc(sizeof(double) * 10);
    for(int i=0;i<10;i++)
        arr[i]=i;

    head=NULL;
    printf("Head:  %s -> null as expected\n", head);
    append(&head,2);
    append(&head,4);
    clearList(head,arr);
    for(int i=0;i<10;i++)
        printf("No %d : %.2f\n",i,arr[i]);

    printf("Head:  %s -> Not null as linkedlist is not freed\n", head);
    head=freeList(head);
    printf("Head:  %s -> Again null as expected\n", head);
    free(arr);
    printf("%s", head);
    getchar();
    return 0;
    }
...