Thread: Memory leak on readline

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    4

    Memory leak on readline

    Code:
    #include <stdlib.h>
    #include <readline/readline.h>
    
    
    int main(){
            int i;
            for(i=0; i<10; i++){
                    char *a = readline("Insert some text: ");
                    free(a);
            }
            return 0;
    }
    I think this should have no memory leaks, but valgrind reports some.
    ==9908==
    ==9908== HEAP SUMMARY:
    ==9908== in use at exit: 63,725 bytes in 171 blocks
    ==9908== total heap usage: 318 allocs, 147 frees, 71,388 bytes allocated
    ==9908==
    ==9908== LEAK SUMMARY:
    ==9908== definitely lost: 0 bytes in 0 blocks
    ==9908== indirectly lost: 0 bytes in 0 blocks
    ==9908== possibly lost: 0 bytes in 0 blocks
    ==9908== still reachable: 63,725 bytes in 171 blocks
    ==9908== suppressed: 0 bytes in 0 blocks
    What i am doing wrong?

  2. #2
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    We'd have to see readline(). It's not a standard C function.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    "Still reachable" doesn't always mean it's an actual leak. You may not have to worry about it. Re-run valgrind with the flags "--leak-check=full --show-reachable=yes" and interpret that output.

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    4
    This is the last part:

    ==10279== 5,964 bytes in 1 blocks are still reachable in loss record 34 of 35
    ==10279== at 0x4024F12: calloc (vg_replace_malloc.c:467)
    ==10279== by 0x41EF8E6: ??? (in /lib/libncurses.so.5.7)
    ==10279== by 0x41EFED2: _nc_find_type_entry (in /lib/libncurses.so.5.7)
    ==10279== by 0x41F3092: tgetstr (in /lib/libncurses.so.5.7)
    ==10279== by 0x406014D: _rl_init_terminal_io (in /lib/libreadline.so.6.1)
    ==10279== by 0x40485D8: rl_initialize (in /lib/libreadline.so.6.1)
    ==10279== by 0x40495AD: readline (in /lib/libreadline.so.6.1)
    ==10279== by 0x80484E2: main (in /home/quarter/a.out)
    ==10279==
    ==10279== 16,448 bytes in 8 blocks are still reachable in loss record 35 of 35
    ==10279== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
    ==10279== by 0x4063DF1: xmalloc (in /lib/libreadline.so.6.1)
    ==10279== by 0x404CB3D: rl_make_bare_keymap (in /lib/libreadline.so.6.1)
    ==10279== by 0x40546D0: rl_generic_bind (in /lib/libreadline.so.6.1)
    ==10279== by 0x4054A07: rl_bind_keyseq (in /lib/libreadline.so.6.1)
    ==10279== by 0x40552A7: rl_parse_and_bind (in /lib/libreadline.so.6.1)
    ==10279== by 0x405540D: ??? (in /lib/libreadline.so.6.1)
    ==10279== by 0x40485FE: rl_initialize (in /lib/libreadline.so.6.1)
    ==10279== by 0x40495AD: readline (in /lib/libreadline.so.6.1)
    ==10279== by 0x80484E2: main (in /home/quarter/a.out)
    ==10279==
    ==10279== LEAK SUMMARY:
    ==10279== definitely lost: 0 bytes in 0 blocks
    ==10279== indirectly lost: 0 bytes in 0 blocks
    ==10279== possibly lost: 0 bytes in 0 blocks
    ==10279== still reachable: 63,723 bytes in 171 blocks
    ==10279== suppressed: 0 bytes in 0 blocks


  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Yeah, I've seen many of those. I don't think it's anything you need to worry about, as long as it's under "Still reachable". I'm not sure even what it means, but I've never seen anything you'd have to worry about under there. Only the three "lost" above are potentially dangerous.
    Maybe someone else can verify and clarify on what exactly it means.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by quarter82 View Post
    Code:
    #include <stdlib.h>
    #include <readline/readline.h>
    
    
    int main(){
            int i;
            for(i=0; i<10; i++){
                    char *a = readline("Insert some text: ");
                    free(a);
            }
            return 0;
    }
    I think this should have no memory leaks, but valgrind reports some.


    What i am doing wrong?
    Well for starts you are reporting memory leaks in a self-written function but didn't bother to post the function. Post your readline code.

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    4

  8. #8
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Complicated and confusing instructions. I never got the sense of what this function is all about... only that it's part of much more confusing set of other possibly capable functions and parameters. Nowhere did I see where it says the function allocates memory, but the example code seems to imply it does.

    One of the samples shows that if readline() returns NULL it means an EOF condition was met. In that case you shouldn't be freeing a NULL pointer.

  9. #9
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    "Still reachable" means memory that hasn't been freed, but pointers to it still exist. Whether it's acceptable depends on how you feel about letting memory be freed at program exit. If some memory has to live for the entire length of the program (but cannot, for whatever reason, be statically allocated), there's no harm in not freeing it, since at program exit, it will be freed (if it's not, your operating system is broken, and you've got no guarantee that free() would free the memory back to the OS either).

    It sounds like readline() performs an initialization the first time it's called, and this involves allocating memory that is never freed. It's possible the readline API has a call to free it, but it might not. In any case it's really not harmful; you should mainly be worried about memory valgrind reports that might be or definitely is lost.
    In that case you shouldn't be freeing a NULL pointer.
    free(NULL) is safe; it does nothing.

  10. #10
    Registered User
    Join Date
    Mar 2011
    Posts
    4
    Thanks for the help guys. I think i'll just leave like it is now

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cas View Post
    "Still reachable" means memory that hasn't been freed, but pointers to it still exist. Whether it's acceptable depends on how you feel about letting memory be freed at program exit. If some memory has to live for the entire length of the program (but cannot, for whatever reason, be statically allocated), there's no harm in not freeing it, since at program exit, it will be freed (if it's not, your operating system is broken, and you've got no guarantee that free() would free the memory back to the OS either).
    The problem with being lazy like this, is exactly what's happening right here right now. You end up sitting around wondering "Is this a leak or is it okay?"

    If you assume the attitude that a block that isn't freed is never okay, answering this question becomes a lot simpler.

    EDIT: If you look at those call stack, you see that the blocks were allocated underneath a call to rl_initialize(), so these are probably blocks that get allocated once when readline initializes itself, then it gets lazy and doesn't free them. I can't imagine why the authors think that's acceptable, but it's not unusual to see such things
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #12
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Readline memory leak - Bug reports for GNU readline library - ArchiveOrange
    Reading readline source code confirmed this.
    They have static variables(pointers) that are initialized using malloc for the first time call.
    Last edited by Bayint Naung; 04-03-2011 at 10:57 PM.

  13. #13
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by brewbuck View Post
    The problem with being lazy like this, is exactly what's happening right here right now. You end up sitting around wondering "Is this a leak or is it okay?"

    If you assume the attitude that a block that isn't freed is never okay, answering this question becomes a lot simpler.
    This is my only problem with my mac. The following program:
    Code:
    int main(){}
    Gives the following output on valgrind:
    ==290== 88 bytes in 1 blocks are still reachable in loss record 1 of 1
    ==290== at 0x10000FD65: malloc (vg_replace_malloc.c:236)
    ==290== by 0x1001030EB: get_or_create_key_element (in /usr/lib/libSystem.B.dylib)
    ==290== by 0x100103008: _keymgr_get_and_lock_processwide_ptr_2 (in /usr/lib/libSystem.B.dylib)
    ==290== by 0x100102FCF: __keymgr_initializer (in /usr/lib/libSystem.B.dylib)
    ==290== by 0x1001015E7: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
    ==290== by 0x7FFF5FC0D4FF: ImageLoaderMachO::doModInitFunctions(ImageLoader:: LinkContext const&) (in /usr/lib/dyld)
    ==290== by 0x7FFF5FC0BCEB: ImageLoader::recursiveInitialization(ImageLoader:: LinkContext const&, unsigned int) (in /usr/lib/dyld)
    ==290== by 0x7FFF5FC0BC9C: ImageLoader::recursiveInitialization(ImageLoader:: LinkContext const&, unsigned int) (in /usr/lib/dyld)
    ==290== by 0x7FFF5FC0BDA5: ImageLoader::runInitializers(ImageLoader::LinkCont ext const&) (in /usr/lib/dyld)
    ==290== by 0x7FFF5FC020EE: dyld::initializeMainExecutable() (in /usr/lib/dyld)
    ==290== by 0x7FFF5FC06980: dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**) (in /usr/lib/dyld)
    ==290== by 0x7FFF5FC016D1: dyldbootstrap::start(macho_header const*, int, char const**, long) (in /usr/lib/dyld)
    ==290==
    ==290== LEAK SUMMARY:
    ==290== definitely lost: 0 bytes in 0 blocks
    ==290== indirectly lost: 0 bytes in 0 blocks
    ==290== possibly lost: 0 bytes in 0 blocks
    ==290== still reachable: 88 bytes in 1 blocks
    ==290== suppressed: 0 bytes in 0 blocks
    Ever since, I've stopped caring about "still reachable".

  14. #14
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Ever since, I've stopped caring about "still reachable".
    Valgrind should come with a suppression file for system libraries that have (or appear to have) problems so that they don't get in the way of your program's output. Apparently not all are covered on your OS, but you should be able to create your own suppression file.

    Of course, I don't generally care about "still reachable" either, but I do prefer not having the output of system libraries mixed in with my code's output.

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cas View Post
    Valgrind should come with a suppression file for system libraries that have (or appear to have) problems so that they don't get in the way of your program's output. Apparently not all are covered on your OS, but you should be able to create your own suppression file.
    I don't think you should discount still-reachable blocks without figuring out exactly what's happening. It could still indicate a problem. Holding on to a reference longer than necessary is a form of resource leak which can occur even in fully garbage-collected languages. This is a clear-cut case of a library being stupid, but if you see these in your own code I wouldn't just ignore them.

    Of course, I don't generally care about "still reachable" either, but I do prefer not having the output of system libraries mixed in with my code's output.
    Libraries that spray are evil, whether they spray crap to stdout, debug messages in the debug log, or warnings when running under a debugging tool. I'm with you on that one.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory leak in this case?
    By George2 in forum C++ Programming
    Replies: 3
    Last Post: 03-22-2008, 05:05 AM
  2. memory leak in the code?
    By George2 in forum C++ Programming
    Replies: 20
    Last Post: 01-13-2008, 06:50 AM
  3. Is this code memory leak free? ---> POSIX Threads
    By avalanche333 in forum C++ Programming
    Replies: 9
    Last Post: 04-13-2007, 03:19 PM
  4. Any Memory Leak Checking Tool?
    By George2 in forum C Programming
    Replies: 4
    Last Post: 06-21-2006, 11:02 PM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM