Page 90 - C-Language
P. 90

In contrast, the code below also uses the getline() function, but this time, the allocated memory is
        correctly freed, avoiding a leak.


         #include <stdlib.h>
         #include <stdio.h>

         int main(void)
         {
             char *line = NULL;
             size_t size = 0;

             for(;;) {
                 if (getline(&line, &size, stdin) < 0) {
                     free(line);
                     line = NULL;

                     /* Handle failure such as setting flag, breaking out of loop and/or exiting */
                 }

                 /* <do whatever> */

                 free(line);
                 line = NULL;

             }

             return 0;
         }


        Leaking memory doesn't always have tangible consequences and isn't necessarily a functional
        problem. While "best practice" dictates rigorously freeing memory at strategic points and
        conditions, to reduce memory footprint and lower risk of memory exhaustion, there can be
        exceptions. For example, if a program is bounded in duration and scope, the risk of allocation
        failure might be considered too small to worry about. In that case, bypassing explicit deallocation
        might be considered acceptable. For example, most modern operating systems automatically free
        all memory consumed by a program when it terminates, whether it is due to program failure, a
        system call to exit(), process termination, or reaching end of main(). Explicitly freeing memory at
        the point of imminent program termination could actually be redundant or introduce a performance
        penalty.


        Allocation can fail if insufficient memory is available, and handling failures should be accounted for
        at appropriate levels of the call stack. getline(), shown above is an interesting use-case because
        it is a library function that not only allocates memory it leaves to the caller to free, but can fail for a
        number of reasons, all of which must be taken into account. Therefore, it is essential when using a
        C API, to read the documentation (man page) and pay particular attention to error conditions and
        memory usage, and be aware which software layer bears the burden of freeing returned memory.

        Another common memory handling practice is to consistently set memory pointers to NULL
        immediately after the memory referenced by those pointers is freed, so those pointers can be
        tested for validity at any time (e.g. checked for NULL / non-NULL), because accessing freed
        memory can lead to severe problems such as getting garbage data (read operation), or data
        corruption (write operation) and/or a program crash. In most modern operating systems, freeing
        memory location 0 (NULL) is a NOP (e.g. it is harmless), as required by the C standard — so by



        https://riptutorial.com/                                                                               66
   85   86   87   88   89   90   91   92   93   94   95