2011-08-11 30 views
30

我有一個非常簡單的C代碼來構建一個單鏈表,如下所示,其中我使用malloc爲每個節點動態分配內存。在代碼結束時,我想釋放分配給每個節點的內存,想知道如何去做 - 如果我先從頭節點開始並釋放它,則指向後續節點的指針會丟失併發生內存泄漏。另一種方式是從頭節點開始,並將節點指針保存在單獨的指針數組中,在存儲節點指針的同時遍歷列表直到尾指針,並且一旦到達尾節點,就將其存儲到另一個指針數組,並開始向後釋放該數組索引,直到頭節點被釋放爲止。LinkedList - 如何釋放使用malloc分配的內存

這是實現我想要做的唯一方法嗎?

如果我不想使用第二個緩衝區,我該如何去做。

#include "stdio.h" 
#include "stdlib.h" 

struct lnk_lst 
{ 
    int val; 
    struct lnk_lst * next; 
}; 

typedef struct lnk_lst item; 


main() 
{ 
    item * curr, * head; 
    int i,desired_value; 

    head = NULL; 

    for(i=1;i<=10;i++) 
    { 
     curr = (item *)malloc(sizeof(item)); 
     curr->val = i; 
     curr->next = head; 
     head = curr; 
    } 

    curr = head; 


    while(curr) { 
     printf("%d\n", curr->val); 
     curr = curr->next; 
    } 

    //How to free the memory for the nodes in this list? 
    for(i=1;i<=10;i++) 
    { 
     free()//?? What logic here 
    } 


} 

回答

58

通常的方法是使用(僞代碼前):

node = head    # start at the head. 
while node != null:  # traverse entire list. 
    temp = node   # save node pointer. 
    node = node.next  # advance to next. 
    free temp   # free the saved one. 
head = null    # finally, mark as empty list. 

其基本思想是記住節點在一個單獨的變量中釋放,然後在釋放它之前前進到下一個節點。

您只需要一次記住一個節點,而不是您建議的整個列表。

在您需要添加到您的代碼,你可以刪除的過程中,使用head作爲連續更新列表頭(因爲它的意思是),並curr來存儲您當前刪除的項目什麼條件:

while ((curr = head) != NULL) { // set curr to head, stop if list empty. 
    head = head->next;   // advance head to next element. 
    free (curr);    // delete saved pointer. 
} 

這比上面的僞代碼稍短,僅僅是因爲它利用了C「速記」的一些操作。

2

您的免費代碼應該如下:

lnk_lst temp = null; 
while(head) 
{ 
    temp = head->next; 
    free(head); 
    head = temp; 
} 

此外,我想你的malloc後添加你可能要檢查的MEM是否成功分配..像

if(curr) 
+1

不,這是行不通的。釋放後您不能訪問頭部。 – duedl0r

+0

srry我的壞..我很着急,我錯過了那部分.. – Baz1nga

1

使用與上面相同的邏輯遍歷列表。您保存curr->下一指針的地方,釋放CURR結構,並與保存curr->下一個指針分配CURR

9

我用的是這樣的:垃圾

for (p = curr; NULL != p; p = next) { 
    next = p->next; 
    free(p); 
} 
-1

內容Collector.h

#define Stack struct _stack 
#define _MALLOC_S(type,num) (type *)_GC_malloc(sizeof(type)*num) 
#pragma pack(1) 

//Structure for adressing alocated memory into. 

Stack { 

    int *adress_i; 
    char *adress_c; 
    float *adress_f; 
    double *adress_d; 
    Stack *next; 
}; 

//Safe malloc 

void *_GC_malloc(size_t size) 
{ 
    void* ptr = malloc(size); 
    if(ptr == NULL) 
     return _GC_malloc(size); 
    else 
     return ptr; 
} 

//Push new element on Stack after every malloc 

void Add_New(int *i, float *f , double *d , char *c , Stack *p) 
{ 
    Stack *q = _MALLOC_S(Stack,1); 

     q->adress_i = i; 
     q->adress_f = f; 
     q->adress_c = c; 
     q->adress_d = d; 

     q->next = p->next; 
     p->next = q; 
     q = NULL; 
} 

//before ending program remove adresses that was allocated in memory, and pop entire Stack 

void Free_All(Stack *p) 
{ 
    //free head (dummy element) 
    Stack *Temp = p->next; 
    Stack *_free = p; 
    free(_free); 

    void *oslobodi; 

    while(Temp != NULL) 
    { 
     _free = Temp; 
     Temp = _free->next; 

     if(_free->adress_i != NULL){ 
      oslobodi = _free->adress_i; 
      free((int *)oslobodi); 
     } 
     else if(_free->adress_c != NULL){ 
      oslobodi = _free->adress_c; 
      free((char *)oslobodi); 
     } 
     else if(_free->adress_f != NULL){ 
      oslobodi = _free->adress_f; 
      free((float *)oslobodi); 
     } 
     else{ 
      oslobodi = _free->adress_d; 
      free((double *)oslobodi); 
     } 

     free(_free); 
    } 

    _free = p = Temp; 
} 

/* 
    declare variable (var) and dinamicly alocate memory with simple macro, 
    and add to stack of linked list 
*/ 

#define obj_int(var)  int *var = _MALLOC_S(int,1);  *var = 0; Add_New(var, NULL, NULL, NULL, Head); 
#define obj_char(var)  char *var = _MALLOC_S(char,1); *var = 0; Add_New(NULL, NULL, NULL, var, Head); 
#define obj_float(var)  float *var = _MALLOC_S(float,1); *var = 0; Add_New(NULL, var, NULL, NULL, Head); 
#define obj_double(var)  double *var = _MALLOC_S(double,1); *var = 0; Add_New(NULL, NULL, var, NULL, Head); 
#define obj_struct(_type,_name) struct _type _*name = (struct _type *)malloc(sizeof(struct _type)); 

#define _INIT_ROW(var,num) for(int i = 0; i < num; i++) var[i] = 0; 

/* 
    same, but for row! 

*/ 

#define row_int(var, num) int *var = _MALLOC_S(int,num);  _INIT_ROW(var,num) Add_New(var, NULL, NULL, NULL, Head); 
#define row_char(var, num) char *var = _MALLOC_S(char,num);  _INIT_ROW(var,num) Add_New(NULL, NULL, NULL, var, Head); 
#define row_float(var, num) float *var = _MALLOC_S(float,num);  _INIT_ROW(var,num) Add_New(NULL, var, NULL, NULL, Head); 
#define row_double(var, num) double *var = _MALLOC_S(double,num); _INIT_ROW(var,num) Add_New(NULL, NULL, var, NULL, Head); 
#define string(var, value) row_char(var, (strlen(value)+1)) strcpy(var, value); 

/* with this you create a Stack and allocate dummy element */ 

#define Main(_type) _type main(void) { Stack *Head = _MALLOC_S(Stack,1); Head->next = NULL; Stack *_q_struct; 

/* with this macro you call function for dealocate memory (garbage collecting)*/ 

#define End   Free_All(Head); } 

/*same thing for the other functions*/ 

#define Function(name_function, _type, ...) _type name_function(##__VA_ARGS__) { Stack *Head = _MALLOC_S(Stack,1); Head->next = NULL; 
#define End_Ret(ret_var)   Free_All(Head); return (ret_var); } 
#define Call(name_function, ...)  name_function(##__VA_ARGS__) 

#define Define_Function(name_function, _type, ...) _type name_function(##__VA_ARGS__); 

some_program.c的示例 PS頭文件系統IO是上面這樣的更多頭文件組! :)

#include <systemIO.h> 

    Main(void)   

     int num_elements = 10; 

     row_int(row_elements, num_elements); //alocating row_elements object 

     for(int i = 0; i < num_elements; i++) 
       row_elements[i] = i; //initializing row_elements 

    End //Garbage delete row_elements and end of program 

    // row_int[0] = 0, row_int[1] = 1 .... 
+2

這是我認爲我見過的最瘋狂的事情... –