C-内存泄漏,即使所有allocs可用

C-内存泄漏,即使所有allocs可用,c,memory-leaks,getline,C,Memory Leaks,Getline,我的程序基本上得到用户的输入,并比较每个单词的字谜。我已经在Unix中编译了这个程序,并针对它运行了valgrind-v,但是我不知道当所有堆分配在退出时都被释放时,内存泄漏会从何而来。这是我的主要方法和valgrind输出 int main() { // Create a head node for the linked list, and a newNode variable to //add to the list struct node *newNod

我的程序基本上得到用户的输入,并比较每个单词的字谜。我已经在Unix中编译了这个程序,并针对它运行了valgrind-v,但是我不知道当所有堆分配在退出时都被释放时,内存泄漏会从何而来。这是我的主要方法和valgrind输出

int main()
{
    // Create a head node for the linked list, and a newNode variable to 
    //add to the list     
    struct node *newNode;
    struct node *head = malloc(sizeof(struct node));
    if(head == NULL)
    {
        fprintf(stderr, "Out of memory. Exiting.\n");
        return 1;
    }
    head->next = NULL;

    // For user input
    char *input = NULL;
    char *data;
    size_t len = 0;

    // Read a line in at a time
    while(getline(&input, &len, stdin) != EOF)
    {
        // Delete newline symbol
        input[strlen(input) - 1] = '\0';
        // Convert string to seperate words
        data = strtok(input, " ");

        // While there are more words from the sentence to read
        while(data != NULL)
        {
            // Check that its a letter
            int i, check = 0, length = strlen(data);
            for(i = 0; i < length; i++)
            {
                if(isalpha(data[i]) == 0)
                {
                    check = -1;
                    break;
                }
            }

            // If a letter, create a node, set the data, and append to the
            // to the linked list
            if(check == 0)
            {
                newNode = malloc(sizeof(struct node));
                if(newNode == NULL)
                {
                    fprintf(stderr, "Out of memory. Exiting.\n");
                    return 1;
                }

                newNode->data = data;
                newNode->next = NULL;

                if(head->next == NULL)
                {
                    head->next = newNode;
                }
                else
                {
                    struct node *current = head;
                    while(current->next != NULL){
                        current = current->next;
                    }

                    current->next = newNode;
                }
            }
            // If not a letter, skip the node creation and output error
            else
            {
                fprintf(stderr, "Bad word %s\n", data);
            }

            data = strtok(NULL, " ");

        }

        input = NULL;
        data  = NULL;
    }

    print_anagrams(head->next);
    // Free all mallocs and pointers
    free(newNode);
    free(head);
    free(input);
    free(data);

    return 0;
}

您的代码中有两个问题:

您不应该释放数据,因为它是从调用strtok返回的,不是malloced指针,只是getline返回的输入中字符串的指针。这通常会导致Valgrind报告中出现无效的释放错误 在循环结束时将input设置为NULL,因此基本上丢失了getLine返回的内存指针。您应该在适当的位置释放循环内的输入,这会导致Valgrind报告中的内存泄漏错误
数据不是一个指向输入中的字符串的指针,该字符串由getline进行malloc'ed。释放它的问题在于它可能不指向getline分配的块的开头。一个很好的提示是,在一个大小为120的块中,getLine中的默认分配大小如果他恰好有来自strtok的第一个令牌的数据点,那么他实际上是在释放输入,在将数据复制并存储到单独的内存块中之后,他无论如何都应该这样做。使用getline的大规则,您不能丢失对输入分配开始的引用,也不能丢失释放getline分配的块的能力。分配新的块来存储输入的一部分总是更好的,这样输入就可以留在getline中供其在后续读取时重用。最好是将malloced缓冲区作为输入发送到getline。如果需要,它可以调整大小。继续为多个调用发送相同的输入指针,并在退出循环后释放它。这也清楚地确定了谁是代码读取器的内存所有者。如果您释放行,则链表中存储的所有数据指针都将被挂起。如果您使用getline,并且在出口处看到正在使用:1个块中有120个字节,然后,这将提示您,在您的案例中,您无法释放或误用由getline input分配的缓冲区。getline缓冲区的默认分配大小为120字节。
==32070== Invalid free() / delete / delete[] / realloc()
==32070==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070==    by 0x400F43: main (anagrams2.c:192)
==32070==  Address 0x51fc1f0 is 0 bytes inside a block of size 120 free'd
==32070==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070==    by 0x400F0F: main (anagrams2.c:187)
==32070==
==32070==
==32070== HEAP SUMMARY:
==32070==     in use at exit: 120 bytes in 1 blocks
==32070==   total heap usage: 5 allocs, 5 frees, 288 bytes allocated
==32070==
==32070== Searching for pointers to 1 not-freed blocks
==32070== Checked 80,264 bytes
==32070==
==32070== 120 bytes in 1 blocks are definitely lost in loss record 1 of 1
==32070==    at 0x4C2AB80: malloc (in /usr/lib/valgrind
/vgpreload_memcheck-amd64-linux.so)
==32070==    by 0x4EA5F54: getdelim (iogetdelim.c:66)
==32070==    by 0x400EF9: main (anagrams2.c:131)
==32070==
==32070== LEAK SUMMARY:
==32070==    definitely lost: 120 bytes in 1 blocks
==32070==    indirectly lost: 0 bytes in 0 blocks
==32070==      possibly lost: 0 bytes in 0 blocks
==32070==    still reachable: 0 bytes in 0 blocks
==32070==         suppressed: 0 bytes in 0 blocks
==32070==
==32070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==32070==
==32070== 1 errors in context 1 of 2:
==32070== Invalid free() / delete / delete[] / realloc()
==32070==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070==    by 0x400F43: main (anagrams2.c:192)
==32070==  Address 0x51fc1f0 is 0 bytes inside a block of size 120 free'd
==32070==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070==    by 0x400F0F: main (anagrams2.c:187)
==32070==
==32070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)