Thread: memory leak with getaddrinfo_a

  1. #1
    Registered User
    Join Date
    Dec 2015
    Posts
    13

    memory leak with getaddrinfo_a

    Hi there!


    I got a memory leak using the call 'getaddrinfo_a'. This is an example code taken from the Linux man pages:


    Code:
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main(int argc, char *argv[])
    {
        int i, ret;
        struct gaicb * reqs[argc - 1];
        char host[NI_MAXHOST];
        struct addrinfo *res;
    
    
        if (argc < 2)
        {
            fprintf(stderr, "Usage: %s HOST...\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    
    
        for (i = 0; i < argc - 1; i++)
        {
            reqs[i] = (gaicb*)malloc(sizeof (*reqs[0]));
            if (reqs[i] == NULL)
            {
                perror("malloc");
                exit(EXIT_FAILURE);
            }
            memset(reqs[i], 0, sizeof (*reqs[0]));
            reqs[i]->ar_name = argv[i + 1];
        }
    
    
        ret = getaddrinfo_a(GAI_WAIT, reqs, argc - 1, NULL);
        if (ret != 0)
        {
            fprintf(stderr, "getaddrinfo_a() failed: %s\n",
                    gai_strerror(ret));
            exit(EXIT_FAILURE);
        }
    
    
        for (i = 0; i < argc - 1; i++)
        {
            printf("%s: ", reqs[i]->ar_name);
            ret = gai_error(reqs[i]);
            if (ret == 0)
            {
                res = reqs[i]->ar_result;
    
    
                ret = getnameinfo(res->ai_addr, res->ai_addrlen,
                        host, sizeof (host),
                        NULL, 0, NI_NUMERICHOST);
                if (ret != 0)
                {
                    fprintf(stderr, "getnameinfo() failed: %s\n",
                            gai_strerror(ret));
                    exit(EXIT_FAILURE);
                }
                puts(host);
                
                /*
                 * Still got a memory leak with these lines
                freeaddrinfo(reqs[i]->ar_result);
                free (reqs[i]);
                */
            }
            else
            {
                puts(gai_strerror(ret));
            }
        }
        exit(EXIT_SUCCESS);
    }

    I added the commented lines, but still got the memory leak.


    And these are the error messages showed by valgrind:


    Code:
    ==8866== 272 bytes in 1 blocks are possibly lost in loss record 5 of 6
    ==8866==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==8866==    by 0x40138A4: allocate_dtv (dl-tls.c:322)
    ==8866==    by 0x40138A4: _dl_allocate_tls (dl-tls.c:539)
    ==8866==    by 0x541026E: allocate_stack (allocatestack.c:588)
    ==8866==    by 0x541026E: pthread_create@@GLIBC_2.2.5 (pthread_create.c:539)
    ==8866==    by 0x4E3B49A: __gai_create_helper_thread (gai_misc.h:113)
    ==8866==    by 0x4E3B49A: __gai_enqueue_request (gai_misc.c:256)
    ==8866==    by 0x4E3BBB4: getaddrinfo_a (getaddrinfo_a.c:67)
    ==8866==    by 0x400AE4: main (getaddrinfo_a_example.cpp:31)
    ==8866==
    ==8866== LEAK SUMMARY:
    ==8866==    definitely lost: 0 bytes in 0 blocks
    ==8866==    indirectly lost: 0 bytes in 0 blocks
    ==8866==      possibly lost: 272 bytes in 1 blocks
    ==8866==    still reachable: 2,588 bytes in 9 blocks
    ==8866==         suppressed: 0 bytes in 0 blocks
    ==8866== Reachable blocks (those to which a pointer was found) are not shown.
    ==8866== To see them, rerun with: --leak-check=full --show-leak-kinds=all
    ==8866==
    ==8866== For counts of detected and suppressed errors, rerun with: -v
    ==8866== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

    Why am I having a memory leak with getaddrinfo_a?


    Thanks a lot!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    Well apparently, getaddrinfo_a() creates a thread on your behalf behind the scenes. But there doesn't seem to be any mechanism to notify that thread to quit.

    getaddrinfo_a(3) - Linux manual page
    If you're just going to use GAI_WAIT, you may as well just call getaddrinfo() and save yourself a lot of bother.

    The correct way to exit main() once it is in a threaded environment is to call pthread_exit().
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2015
    Posts
    13
    Hi Salem thanks for your quick response!


    In my original code I am using GAI_NOWAIT, but I posted that example because is simpler. I can't use getaddrinfo because it can block the calling thread for an unspecified amount of time.


    I also tried to use pthread_exit(NULL), but still got the memory leak.


    Thanks a lot anyway!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. memory leak , help please?
    By thedodgeruk in forum C++ Programming
    Replies: 1
    Last Post: 11-20-2010, 03:29 PM
  2. Memory Leak!!!!
    By subhashish1213 in forum C++ Programming
    Replies: 10
    Last Post: 09-14-2009, 12:01 AM
  3. Replies: 2
    Last Post: 09-28-2006, 01:06 PM
  4. memory leak
    By markucd in forum C++ Programming
    Replies: 14
    Last Post: 06-13-2006, 11:14 AM
  5. memory leak
    By stormbringer in forum C Programming
    Replies: 7
    Last Post: 07-17-2002, 09:56 AM

Tags for this Thread