C - Freeing memory after strdup()

后端 未结 1 615
执念已碎
执念已碎 2021-02-08 01:24

I\'m doing a lesson from the Learn C the Hard way online course. In the code sample below, I don\'t understand why the two free() calls are necessary. I

1条回答
  •  迷失自我
    2021-02-08 01:51

    strdup(3) is documented as

       The strdup() function returns a pointer to a new string which is a
    
       duplicate of the string s.  Memory for the new string is obtained
       with malloc(3), and can be freed with free(3).
    

    BTW, as Matt McNabb commented, strdup is standard in Posix, not in the C99 language specification.

    Of course free only releases the memory zone that you pass it (it does not magically and indirectly free any zone pointed inside the memory zone you pass it). Again, free(3) says:

       The free() function frees the memory space pointed to by ptr, which
       must have been returned by a previous call to malloc(), calloc() or
       realloc().  Otherwise, or if free(ptr) has already been called
       before, undefined behavior occurs.  If ptr is NULL, no operation is
       performed.
    

    Read much more about C dynamic memory allocation. If you don't like that, learn about garbage collection. With C on Linux and some other systems, you could consider using Boehm's conservative garbage collector. You'll then use GC_MALLOC and/or GC_MALLOC_ATOMIC instead of malloc, and GC_STRDUP instead of strdup and you won't bother about free (you might sometimes use GC_FREE if wanted). I find it very useful, but it does have some drawbacks (a bit slower than malloc, and no explicit guarantee about releasing memory...).

    Read about memory corruption, and memory leaks

    BTW, you should first compile your program with all warnings and debug info (e.g. gcc -Wall -g). Then you could use your debugger (gdb), set a breakpoint in malloc after main has been reached, and see when malloc is called. You'll see that  strdup is calling malloc ....


    FYI, on Linux, malloc is implemented using mmap(2) -and sometimes the old sbrk(2)- syscalls -to get "large" memory regions (of several kilobytes or even megabytes), and free may sometimes call munmap(2) -for these large regions- but most often it justs mark a freed block as reusable, so that block could be reused in some future calls to malloc. Hence a program doing malloc and free might not release all it previously used memory to the kernel. See also this question about memory fragmentation.

    use also Valgrind and the address sanitizer

    On some operating systems (e.g. Linux) you could compile your C code (using GCC) using gcc -Wall -Wextra -g then use the valgrind tool at runtime. It slows down the execution, but it is helpful in finding bugs like some memory leaks and some buffer overflow. With a recent GCC or Clang compiler, you could also use -at compile time- its address sanitizer (instrumenting the generated code).

    You might also read the GC handbook, related to memory allocation and garbage collection algorithms.

    0 讨论(0)
提交回复
热议问题