
Tips and Tricks to avoid memory leaks in writing C - naughtysriram
When I write C I used to prototype the model first, then fix the memory leaks. I think its OK for throw code. I find that these leaks are mostly due to patterns of code that one avoids.<p>Like,<p>1. not assigning null to a pointer after freeing it<p>2. not allocating enough memory for string processing<p>Please throw in your tips and tricks to avoid memory leaks and memory related problems.
======
_delirium
A common issue for people coming from garbage-collected languages is to be
_very_ aware of what happens when you malloc() inside a function and return a
pointer. Someone is going to have to free it! One common pattern is to have
this malloc()ing be restricted to an obviously named foo_init() function, and
then pair it with a foo_free() function that gets passed the relevant data
structure, and frees anything that the _init() function malloc()ed. You then
keep the _init() and _free() functions together and update them in parallel,
so all the malloc()s in one are paired with a corresponding free() in the
other.

------
JoachimSchipper
"Exceptions" can be useful: lots of my code looks like

    
    
        int fd = -1;
        char *buf = NULL
        if ((fd = open("/foo", O_RDONLY, 0)) == -1)
            goto err;
        if ((buf = malloc(1024)) == NULL)
            goto err;
        ...
        return 0;
        err:
        if (fd =! -1)
            close(fd);
        free(buf);
        return -1;

~~~
naughtysriram
Nice idea, but people would scream seeing those goto's. I used to do those in
a macro/function like,

#define memalloc(x,y) { x=0;if(x=malloc(y)){}else{printf("error:no mem");} }

------
lea
a simple and efficient method for finding memory leaks is replacing
malloc/free with house-keeping macros when debugging:

    
    
      #include <stdlib.h>
      #include <stdio.h>
    
      void *(*_malloc_old) (size_t size) = malloc;
      void (*_free_old) (void *ptr) = free;
    
      #define malloc(size) _malloc_new (size, __FUNCTION__, __LINE__)
      #define free(ptr) _free_new (ptr)
    
      struct alloc
      {
            const char *function;
            int line;
            void *ptr;
            struct alloc *next;
      };
      struct alloc *list = NULL;
    
      void *_malloc_new (size_t size, const char *function, int line)
      {
            struct alloc *e = _malloc_old (sizeof *e);
            void *ptr = _malloc_old (size);
    
            e->function = function;
            e->line = line;
            e->ptr = ptr;
    
            e->next = list;
            list = e;
    
            return (ptr);
      }
      void *_free_new (void *ptr)
      {
            struct alloc *prev = NULL, *e = list;
            while (e) {
                    if (e->ptr == ptr) {
                            break;
                    }
                    prev = e;
                    e = e->next;
            }
            if (e) {
                    if (e == list) {
                            list = NULL;
                    }
                    if (prev) {
                            prev->next = e->next;
                    }
                    _free_old (e);
            }
            _free_old (ptr);
      }
      void pallocs (FILE *f)
      {
            struct alloc *e = list;
            while (e) {
                    fprintf (f, "%s:%d\t0x%x\n", e->function, e->line, (size_t)e->ptr);
                    e = e->next;
            }
    
      }
      int main ()
      {
            void *ptr = malloc (1024);
            void *leak = malloc (1024);
            void *leak2 = malloc (1024);
    
            printf ("before free:\n");
            pallocs (stdout);
    
            printf ("after free:\n");
            free (ptr);
    
            pallocs (stdout);
      }
    

outputs:

    
    
      before free:
      main:67 0x9dab860
      main:66 0x9dab440
      main:65 0x9dab020
      after free:
      main:67 0x9dab860
      main:66 0x9dab440

