c中内存泄漏的原因是什么?
What is the cause of the memory leak in c?
我在用 c 语言创建链表时遇到了内存泄漏。 Valgrind 告诉我问题的根源在第 15 行,但我仍然看不到问题。不知道问题出在哪里,我觉得很愚蠢,但如果你能帮助我,那就太好了!提前致谢!
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct node
{
int number;
struct node *next;
}
node;
int main(void)
{
node *list = malloc(sizeof(node));
if (list == NULL)
{
return 1;
}
list = NULL;
// create link list
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
free(list);
return 1;
}
n->number = i+1;
n->next = NULL;
n->next = list;
list = n;
}
//print link list
for (node *tmp = list; tmp != NULL; tmp = tmp->next)
{
printf("%d - ", tmp->number);
}
printf("\n");
//free link list
while (list != NULL)
{
node *tmp = list->next;
free(list);
list = tmp;
}
}
这是我的 valgrind 输出:
==3895== Memcheck, a memory error detector
==3895== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3895== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3895== Command: ./temp
==3895==
3 - 2 - 1 -
==3895==
==3895== HEAP SUMMARY:
==3895== in use at exit: 16 bytes in 1 blocks
==3895== total heap usage: 4 allocs, 3 frees, 64 bytes allocated
==3895==
==3895== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3895== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3895== by 0x401168: main (temp.c:15)
==3895==
==3895== LEAK SUMMARY:
==3895== definitely lost: 16 bytes in 1 blocks
==3895== indirectly lost: 0 bytes in 0 blocks
==3895== possibly lost: 0 bytes in 0 blocks
==3895== still reachable: 0 bytes in 0 blocks
==3895== suppressed: 0 bytes in 0 blocks
==3895==
==3895== For lists of detected and suppressed errors, rerun with: -s
==3895== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
指针只是一个存储内存地址的变量。您使用 malloc malloc(sizeof(node))
获得了内存地址,但是您将 null 放入其中 list = NULL
并且您丢失了地址。这不就是你想要的吗?
node** list;
size_t i;
list = malloc(sizeof(node*));
*list = NULL;
for (i = 0; i < 3; i++)
{
node* n = malloc(sizeof(node));
n->number = i + 1;
n->next = *list;
*list = n;
}
/* print node... */
/* release node... free(n) */
free(list);
list = NULL;
可见这次分配内存
node *list = malloc(sizeof(node));
if (list == NULL)
{
return 1;
}
list = NULL;
是多余的,会产生内存泄漏,因为指针list
在内存分配后被重新赋值。结果,分配的内存地址丢失了。
随便写
node *list = NULL;
也在这个代码片段中
n->number = i+1;
n->next = NULL;
n->next = list;
list = n;
此声明
n->next = NULL;
是多余的。
在for循环中
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
free(list);
return 1;
}
//...
您需要释放所有分配的内存。
例如
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
while ( list )
{
node *tmp = list;
list = list->next;
free( tmp );
}
return 1;
}
//...
为避免代码重复,您可以编写一个单独的函数来释放分配的内存。例如
void free_list( node **list )
{
while ( *list )
{
node *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
}
并像这样称呼它
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
free_list( &list );
return 1;
}
//...
或者像
这样的程序结束
free_list( &list );
我在用 c 语言创建链表时遇到了内存泄漏。 Valgrind 告诉我问题的根源在第 15 行,但我仍然看不到问题。不知道问题出在哪里,我觉得很愚蠢,但如果你能帮助我,那就太好了!提前致谢!
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct node
{
int number;
struct node *next;
}
node;
int main(void)
{
node *list = malloc(sizeof(node));
if (list == NULL)
{
return 1;
}
list = NULL;
// create link list
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
free(list);
return 1;
}
n->number = i+1;
n->next = NULL;
n->next = list;
list = n;
}
//print link list
for (node *tmp = list; tmp != NULL; tmp = tmp->next)
{
printf("%d - ", tmp->number);
}
printf("\n");
//free link list
while (list != NULL)
{
node *tmp = list->next;
free(list);
list = tmp;
}
}
这是我的 valgrind 输出:
==3895== Memcheck, a memory error detector
==3895== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3895== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3895== Command: ./temp
==3895==
3 - 2 - 1 -
==3895==
==3895== HEAP SUMMARY:
==3895== in use at exit: 16 bytes in 1 blocks
==3895== total heap usage: 4 allocs, 3 frees, 64 bytes allocated
==3895==
==3895== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3895== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3895== by 0x401168: main (temp.c:15)
==3895==
==3895== LEAK SUMMARY:
==3895== definitely lost: 16 bytes in 1 blocks
==3895== indirectly lost: 0 bytes in 0 blocks
==3895== possibly lost: 0 bytes in 0 blocks
==3895== still reachable: 0 bytes in 0 blocks
==3895== suppressed: 0 bytes in 0 blocks
==3895==
==3895== For lists of detected and suppressed errors, rerun with: -s
==3895== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
指针只是一个存储内存地址的变量。您使用 malloc malloc(sizeof(node))
获得了内存地址,但是您将 null 放入其中 list = NULL
并且您丢失了地址。这不就是你想要的吗?
node** list;
size_t i;
list = malloc(sizeof(node*));
*list = NULL;
for (i = 0; i < 3; i++)
{
node* n = malloc(sizeof(node));
n->number = i + 1;
n->next = *list;
*list = n;
}
/* print node... */
/* release node... free(n) */
free(list);
list = NULL;
可见这次分配内存
node *list = malloc(sizeof(node));
if (list == NULL)
{
return 1;
}
list = NULL;
是多余的,会产生内存泄漏,因为指针list
在内存分配后被重新赋值。结果,分配的内存地址丢失了。
随便写
node *list = NULL;
也在这个代码片段中
n->number = i+1;
n->next = NULL;
n->next = list;
list = n;
此声明
n->next = NULL;
是多余的。
在for循环中
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
free(list);
return 1;
}
//...
您需要释放所有分配的内存。
例如
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
while ( list )
{
node *tmp = list;
list = list->next;
free( tmp );
}
return 1;
}
//...
为避免代码重复,您可以编写一个单独的函数来释放分配的内存。例如
void free_list( node **list )
{
while ( *list )
{
node *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
}
并像这样称呼它
for (int i = 0; i < 3; i++)
{
node *n = malloc(sizeof(node));
if(n == NULL)
{
free_list( &list );
return 1;
}
//...
或者像
这样的程序结束free_list( &list );