简体   繁体   English

Valgrind指示内存泄漏

[英]Valgrind indicates a memory leak

So, I have some code and Valgrind seems to indicate that there is a memory leak present but I am not seeing it. 因此,我有一些代码,Valgrind似乎表明存在内存泄漏,但我没有看到。 The code in question is 有问题的代码是

void *run_client(void *n)
{

    char recv_buffer[1024];

    // This is random, but right now we will allocate 5120 bytes
    // for the data coming from the instrument.
    const int data_size = 5120;
    int numbytes;

    struct net_info *n_info;
    n_info = (struct net_info *)malloc(sizeof(struct net_info));
    n_info = (struct net_info *)n;

    int clientfd;
    clientfd = init_client(&n_info->cfg);

    while (!*(n_info->flag))
    {
        // Clear the buffer every time...
        memset(recv_buffer, 0, 1024);
        if ((numbytes = recv(clientfd, recv_buffer, data_size - 1, 0)) == -1)
        {
            perror("recv");
            exit(1);
        }
        if (recv_buffer[0] != '{' || recv_buffer[numbytes - 1] != '\n')
            continue;

        // remove last two bytes that are EOL indicators
        numbytes -= 2;
        recv_buffer[numbytes] = 0;

        wclear(n_info->packet_win);
        box(n_info->packet_win, 0, 0);

        mvwprintw(n_info->packet_win, 1, 1, "%s", recv_buffer);
        wrefresh(n_info->packet_win);
    }

    close(clientfd);
    free(n_info);
    return 0;
}

I am not sure if the details are necessary, but they are provided here so that you can understand the context. 我不确定这些细节是否必要,但此处提供了这些细节,以便您了解上下文。 The function above is called from pthread_create and listens on a specified port for data. 上面的函数从pthread_create调用,并在指定的端口上侦听数据。 The string data is then posted to an ncurses window (the code is preliminary and is currently just used for testing). 然后,将字符串数据发布到ncurses窗口中(代码是初步的,当前仅用于测试)。 The function exits when the main loop receives a request to exit and the flag in the while loop is set high. 当主循环收到退出请求并且while循环中的标志设置为高电平时,该函数退出。

The message from Valgrind is 来自Valgrind的消息是

==24037== 88 bytes in 1 blocks are definitely lost in loss record 14 of 55
==24037==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24037==    by 0x401897: run_client (ncurses-cpc.c:60)
==24037==    by 0x52906DA: start_thread (pthread_create.c:463)
==24037==    by 0x57D588E: clone (clone.S:95)

and line 60 refers to n_info = (struct net_info *)malloc(sizeof(struct net_info)); 第60行引用n_info = (struct net_info *)malloc(sizeof(struct net_info)); . As you can see, before exiting the function requests a free of the memory associated with that struct before exiting. 如您所见,在退出函数之前,该函数会在退出之前请求free与该结构关联的内存。 Am I missing something? 我想念什么吗? Why is Valgrind flagging this? 为什么Valgrind标记此? (the message is posted after the heap summary message when valgrind is run with the option leak-check=yes .) (当使用选项leak-check=yes运行valgrind时,该消息将堆摘要消息之后发布。)

From the comments it appears that you want to pass the input struct to the client thread. 从注释看来,您想要将输入结构传递给客户端线程。 The leak appears because you allocate some memory and immediately discard the pointer to it. 出现泄漏是因为您分配了一些内存并立即丢弃了指向它的指针。

No, you cannot just do - 不,你不能只是-

struct net_info *n_info = n;

and free the memory from the main loop, because that would lead to use after free bug. 并从主循环中free内存,因为这将导致释放错误后使用。

What you need to do is transfer the ownership of this buffer to the thread. 您需要做的就是将此缓冲区的所有权转移到线程中。 This basically means that from the point the thread starts, the input buffer is owned by the thread and it is the thread's responsibility to free it. 从根本上讲,这意味着从线程启动时开始,输入缓冲区归线程所有,并且线程有责任free它。

You need to remove the new malloc in the thread and just use the pointer directly. 您需要在线程中删除新的malloc ,然后直接使用指针。 The pointer will be free 'd after the thread is done using it. 线程使用完之后,指针将被free

Also be careful that the main loop (or any other thread) should not be sharing the same buffer. 还应注意主循环(或任何其他线程)不应共享同一缓冲区。 This means that the main loop should malloc a separate buffer for every thread it creates. 这意味着主循环应该为它创建的每个线程malloc一个单独的缓冲区。

n_info = (struct net_info *)malloc(sizeof(struct net_info));

You just allocated memory... and the very next line: 您刚刚分配了内存...以及下一行:

n_info = (struct net_info *)n;

You overwrite n_info with n , losing the reference to the memory you just allocated. 您用n覆盖n_info ,从而丢失了对刚刚分配的内存的引用。 The free() by the end of the function is actually freeing n , not the memory this malloc() allocated. 函数末尾的free()实际上是释放n ,而不是释放此malloc()分配的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM