Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 不了解Valgrind中内存泄漏显示的来源_C_Data Structures_Valgrind_Singly Linked List - Fatal编程技术网

C 不了解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

在花了一天的大部分时间试图用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/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");
}