3 ms·
Tips and Tricks to avoid memory leaks in writing C
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.
Like,
1. not assigning null to a pointer after freeing it
2. not allocating enough memory for string processing
Please throw in your tips and tricks to avoid memory leaks and memory related problems.
- _delirium 15y agoA 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 15y ago"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 15y agoNice 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 15y agoa 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