C语言 LinkedList - 如何释放使用 malloc 分配的内存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7025328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LinkedList - How to free the memory allocated using malloc
提问by goldenmean
I have a very simple C code for constructing a Singly Linked list as below, in which I allocate memory for each node dynamically using malloc. At the end of code, I want to free the memory for each node allocated, was wondering how to go about it - If I start from head node first and free it, the pointers to the subsequent nodes are lost and memory leak happens.
我有一个非常简单的 C 代码来构造一个单链表,如下所示,其中我使用 malloc 为每个节点动态分配内存。在代码的最后,我想为每个分配的节点释放内存,想知道如何去做 - 如果我首先从头节点开始并释放它,那么指向后续节点的指针就会丢失并且会发生内存泄漏。
Other way is start from head node and keep storing the node pointer in a separate array of pointers or something, traverse the list till the tail pointer while storing the node pointers, and once reach the tail node, store that also to the other array of pointers and start freeing from that array index backwards until the head node is free'ed.
另一种方法是从头节点开始并将节点指针存储在一个单独的指针数组或其他东西中,在存储节点指针的同时遍历列表直到尾指针,一旦到达尾节点,也将其存储到另一个数组中指针并开始从该数组索引向后释放,直到头节点被释放。
Is that the only way to achieve what I am trying to do?
这是实现我想要做的事情的唯一方法吗?
In case if I dont want to use second buffer, how do I go about it.
如果我不想使用第二个缓冲区,我该怎么做。
#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
}
}
回答by paxdiablo
The usual way is with (pseudo-code first):
通常的方法是使用(伪代码优先):
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.
The basic idea is to remember the node to free in a separate variable then advance to the next before freeing it.
基本思想是在一个单独的变量中记住要释放的节点,然后在释放它之前前进到下一个。
You only need to remember onenode at a time, not the entire list as you propose.
您一次只需要记住一个节点,而不是您建议的整个列表。
In terms of what you need to add to your code, you can, during deletion, use headas the continuously updating list head (as it's meant to be) and currto store the item you're currently deleting:
就您需要添加到代码中的内容而言,您可以在删除过程中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.
}
This is a little shorter than the pseudo-code above simply because it takes advantage of C "shorthand" for some operations.
这比上面的伪代码要短一些,因为它在某些操作中利用了 C 的“速记”。
回答by cnicutar
I use something like this:
我使用这样的东西:
for (p = curr; NULL != p; p = next) {
next = p->next;
free(p);
}
回答by Baz1nga
Your free code should be as follows:
您的免费代码应如下所示:
lnk_lst temp = null;
while(head)
{
temp = head->next;
free(head);
head = temp;
}
Also I would like to add after your malloc you probably want to check whether the mem was allocated successfully.. something like
此外,我想在您的 malloc 之后添加您可能想要检查内存是否已成功分配.. 类似
if(curr)
回答by duedl0r
You traverse the list using the same logic as above. You save the curr->next pointer somewhere, free the curr struct and assign curr with the saved curr->next pointer
您使用与上述相同的逻辑遍历列表。您将 curr->next 指针保存在某处,释放 curr 结构并使用保存的 curr->next 指针分配 curr
回答by CCC
Content of Garbage Collector.h
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__);
Example of some_program.c P.S. header systemIO is group of more headers like this above! :)
some_program.c PS 标头 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 ....

