C 不了解Valgrind中内存泄漏显示的来源
在花了一天的大部分时间试图用CRUD操作构建我自己的单链表程序之后,我偶然发现了一些项目,并找到了下面的程序作为参考。在这个程序上运行valgrind,虽然它显示内存泄漏,但我不知道它是如何产生的,或者如何消除它。它显示以下位置:C 不了解Valgrind中内存泄漏显示的来源,c,data-structures,valgrind,singly-linked-list,C,Data Structures,Valgrind,Singly Linked List,在花了一天的大部分时间试图用CRUD操作构建我自己的单链表程序之后,我偶然发现了一些项目,并找到了下面的程序作为参考。在这个程序上运行valgrind,虽然它显示内存泄漏,但我不知道它是如何产生的,或者如何消除它。它显示以下位置: ==51957== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==51957== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpre
==51957== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==51957== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==51957== by 0x420959: insert_at_last (sllother.c:110)
==51957== by 0x4218C6: create_linked_list (sllother.c:102)
==51957== by 0x4206F7: main (sllother.c:35)
#include<stdio.h>
#include<stdlib.h>
struct linked_list
{
int number;
struct linked_list *next;
};
typedef struct linked_list node;
node *head=NULL, *last=NULL;
void create_linked_list();
void print_linked_list();
void insert_at_last(int value);
void insert_at_first(int value);
void insert_after(int key, int value);
void delete_item(int value);
void search_item(int value);
int main()
{
int key, value;
//Create a linked list
printf("Create Linked List\n");
create_linked_list();
print_linked_list();
//Insert value at last position to existing Linked List
printf("\nInsert new item at last\n");
scanf("%d", &value);
insert_at_last(value);
print_linked_list();
//Insert value at first position to existing Linked List
printf("\nInsert new item at first\n");
scanf("%d", &value);
insert_at_first(value);
print_linked_list();
//Insert value after a defined value to existing Linked List
printf("\nEnter a KEY (existing item of List), after that you want to insert a value\n");
scanf("%d", &key);
printf("\nInsert new item after %d KEY\n", key);
scanf("%d", &value);
insert_after(key, value);
print_linked_list();
//Search an item from Linked List
printf("\nEnter an item to search it from List\n");
scanf("%d", &value);
search_item(value);
//Delete value from List
printf("\nEnter a value, which you want to delete from list\n");
scanf("%d", &value);
delete_item(value);
print_linked_list();
return 0;
}
/*
User Defined Functions
*/
void create_linked_list()
{
int val;
while(1)
{
printf("Input a number. (Enter -1 to exit)\n");
scanf("%d", &val);
if(val==-1)
break;
insert_at_last(val);
}
}
void insert_at_last(int value)
{
node *temp_node;
temp_node = (node *) malloc(sizeof(node));
temp_node->number=value;
temp_node->next=NULL;
//For the 1st element
if(head==NULL)
{
head=temp_node;
last=temp_node;
}
else
{
last->next=temp_node;
last=temp_node;
}
}
void insert_at_first(int value)
{
node *temp_node = (node *) malloc(sizeof(node));
temp_node->number=value;
temp_node->next = head;
head = temp_node;
}
void insert_after(int key, int value)
{
node *myNode = head;
int flag = 0;
while(myNode!=NULL)
{
if(myNode->number==key)
{
node *newNode = (node *) malloc(sizeof(node));
newNode->number = value;
newNode->next = myNode->next;
myNode->next = newNode;
printf("%d is inserted after %d\n", value, key);
flag = 1;
break;
}
else
myNode = myNode->next;
}
if(flag==0)
printf("Key not found!\n");
}
void delete_item(int value)
{
node *myNode = head, *previous=NULL;
int flag = 0;
while(myNode!=NULL)
{
if(myNode->number==value)
{
if(previous==NULL)
head = myNode->next;
else
previous->next = myNode->next;
printf("%d is deleted from list\n", value);
flag = 1;
break;
}
previous = myNode;
myNode = myNode->next;
}
if(flag==0)
printf("Key not found!\n");
}
void search_item(int value)
{
node *searchNode = head;
int flag = 0;
while(searchNode!=NULL)
{
if(searchNode->number==value)
{
printf("%d is present in this list. Memory address is %d\n", value, searchNode);
flag = 1;
break;
}
else
searchNode = searchNode->next;
}
if(flag==0)
printf("Item not found\n");
}
void print_linked_list()
{
printf("\nYour full linked list is\n");
node *myList;
myList = head;
while(myList!=NULL)
{
printf("%d ", myList->number);
myList = myList->next;
}
puts("");
}
谢谢问题在于删除代码
无效删除项目(int值)
。找到该值后,此函数将泄漏正在删除的节点:
void delete_item(int value) {
node *myNode = head, *previous=NULL;
int flag = 0;
while(myNode!=NULL) {
if(myNode->number==value) {
if(previous==NULL)
head = myNode->next;
else
previous->next = myNode->next;
printf("%d is deleted from list\n", value);
flag = 1;
break;
}
previous = myNode;
myNode = myNode->next;
}
if(flag==0)
printf("Key not found!\n");
}
如您所见,此函数缺少对
free
的调用。您可以通过在中断之前添加对free(myNode)
的调用来解决此问题
谢谢,此操作修复了内存泄漏!我仍在绞尽脑汁研究指针,但我认为只需要释放使用malloc之类的函数存储在堆上的内存。我们从来都没见过malloc myNode?它是否需要被释放,因为存储被删除的值的原始节点是malloc'd,但当它从链表中断开时,它就不包括在main中的自由函数调用中?@Aza是的,另一个函数已经分配了myNode
,所以一旦你从链表中“断开它”,它就会被释放,你需要释放它。请注意,确保头
和最后一个
保持一致非常重要,即使删除最后一个节点也是如此。您当前的代码没有做到这一点:last
如果您删除的myNode
恰好指向last
,则可能会保持“悬空”。好的,再次感谢,我有点自责了,我没有在这里继续,并提前请求您提供了很大的帮助。
void delete_item(int value) {
node *myNode = head, *previous=NULL;
int flag = 0;
while(myNode!=NULL) {
if(myNode->number==value) {
if(previous==NULL)
head = myNode->next;
else
previous->next = myNode->next;
printf("%d is deleted from list\n", value);
flag = 1;
break;
}
previous = myNode;
myNode = myNode->next;
}
if(flag==0)
printf("Key not found!\n");
}