【问题标题】:LinkedList - How to free the memory allocated using mallocLinkedList - 如何释放使用 malloc 分配的内存
【发布时间】:2011-10-24 21:59:41
【问题描述】:

我有一个非常简单的 C 代码用于构造如下所示的单链表,其中我使用 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
   }


}

【问题讨论】:

    标签: c linked-list malloc free


    【解决方案1】:

    你的免费代码应该如下:

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

    另外我想在你的 malloc 之后添加你可能想检查内存是否分配成功.. 类似

    if(curr)
    

    【讨论】:

    • 不,这不起作用。释放后无法访问head。
    • 你不能访问“head”指向的内存,但是给“head”本身分配一个新值是完全可以的。
    【解决方案2】:

    通常的方式是使用(伪代码优先):

    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“速记”的一些操作。

    【讨论】:

      【解决方案3】:

      您使用与上述相同的逻辑遍历列表。您将 curr->next 指针保存在某处,释放 curr 结构并使用保存的 curr->next 指针分配 curr

      【讨论】:

        【解决方案4】:

        我使用这样的东西:

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

        【讨论】:

          【解决方案5】:

          Garbage Collector.h 的内容

          #include <stdlib.h>
          #include <stdint.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 示例 附:标头 systemIO 是一组更多像上面这样的标头! :)

          
          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 .... 
          

          【讨论】:

            猜你喜欢
            • 2021-06-15
            • 2023-01-21
            • 2012-12-07
            • 2015-09-13
            • 1970-01-01
            • 2014-05-27
            • 1970-01-01
            • 2011-10-22
            • 2016-11-16
            相关资源
            最近更新 更多