C - 内存泄漏,即使所有alloc都是免费的

时间:2017-03-10 05:36:15

标签: 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 *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;
}

Valgrind输出

==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)

1 个答案:

答案 0 :(得分:1)

您的代码中存在两个问题:

  1. 你不应该释放data,因为它是从strtok调用返回的,并不是一个malloced指针,只是指向getline返回的输入内部字符串的指针。(这主要是因为Valgrind报告中的无效免费错误)
  2. 在循环结束时将input设置为NULL,因此基本上丢失了指向getLine返回的内存的指针。您应该在适当的位置释放循环内的input(这会导致您在Valgrind报告中出现内存泄漏错误)