如何释放使用malloc分配的内存



我有一个非常简单的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("%dn", 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
   }

}

通常的方法是(伪代码优先):

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语言对一些操作的"速记"。

我使用这样的代码:

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

你的自由代码应该如下:

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

我还想在您的malloc之后添加,您可能想检查mem是否成功分配。就像

if(curr)

使用与上面相同的逻辑遍历列表。你把当前指针保存在某个地方,释放当前结构体并用保存的当前指针赋值当前

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的示例P.S.头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 .... 

相关内容

  • 没有找到相关文章

最新更新