在C中的链表中为头节点分配NULL

时间:2019-01-15 17:22:03

标签: c function pointers linked-list reference

请参阅下面的完整代码。

我有一个名为arr的初始数组。 我正在使用一个链表通过append函数存储一些索引。得到索引后,将它们存储在链接列表中,并使用clearList将相应的值更改为0(在本例中为arr [2]和arr [4])。 最后,由于完成了链接列表,因此我通过调用freeList释放了内存。

但是,为了能够一次又一次地执行相同的操作,每当我调用head时,都需要将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; 
            }
        }
    }

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 :(得分:3)

You're already changing the value of head in your append function so you basically need to do the same thing in 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 */
    }

答案 1 :(得分:1)

仅出于完整性考虑:另一种可能的选择是为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的答案一样。

答案 2 :(得分:0)

I realized it is possible to change the freeList function so that it will return a NULL value. See the updated code below:

#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;
    }