The greatest mistake you can make in life is to be continually fearing you will make one

Wednesday 17 March 2010

Common Problems with malloc() and calloc() functions in C

1) Forgetting to initialize the allocated memory (malloc only)
Example:
int p=malloc((sizeof (int))*5);
p[0]++;

Solution:
The memory allocated using malloc() function contains garbage values.Initialize malloc-ed memory using memset
int *p=malloc((sizeof (int))*5);
memset(p,0, (sizeof (int))*5);
p[0]++;

2) Using more memory than allocated memory
Example:
int *p=calloc((sizeof (int)),5);
p[5]++;

3. Forgetting to allocate memory for storing the null character when using strings
Example
char *p=calloc((sizeof (char)),5);
strcpy(p,"NULL?");

Solution:
char *p=calloc((sizeof (char)),6);
strcpy(p,"NULL?");

4. Referring de-allocated memory (free-d memory)
Example:
int *p=calloc((sizeof (int)),5);
for (i=0;i < 5;i++)
     p[i]=i;
free(p);
...
...
*p=1;

Solution:
The line "*p=1;" could trigger a "Segmentation fault" error during run-time. But not guarenteed always.
This can be hard to trouble-shoot; So it is always a good idea to re-initialize the pointer to NULL after freeing

int *p=calloc((sizeof (int)),5);
for (i=0;i<5;i++) p[i]=i;
free(p);
p=NULL;
...
...
*p=1; == > This always triggers a "Segmentation fault" error during run-time

5. Double free-ing for memory
int *p1,*p2;
p1=calloc((sizeof (int)),5);
p2=p1;
free(p1);
p1=NULL;
...
...
...
*p2=0; // Can result in "Segmentation fault";
free(p2); // Would trigget the runtime error "glibc detected ** ... : double free or corruption"

Both p1 and p2 were pointing to the same memory and called free for that memory
However p2 still points to the memory.

Soln: Remember to re-initialize the copied pointers also to NULL
int p1,*p2;
p1=calloc((sizeof (int)),5);
p2=p1;
free(p1);
p1=NULL;
p2=NULL;
...
...
...
*p2=0; // Will always result in "Segmentation fault";
free(p2); // Will always result in "Segmentation fault";

Hint: Whenever you see the error "Segmentation fault" or "glibc detected ** ... : double free or corruption" error in a "free" call, check if you have already called a free for the same memory

6. Freeing unallocated memory
Example:
The following works fine
#define NEED_MEM 1
int *p;
if (NEED_MEM) {
p=calloc((sizeof (int)),5);
}
...
...
free(p);

But the following doesn't
#define NEED_MEM 0
int *p;
if (NEED_MEM) {
p=calloc((sizeof (int)),5);
}
...
...
free(p); // May result in "Segmentation fault"

Solution:
Always initalize pointers to NULL
#define NEED_MEM 0
int *p=NULL;
if (NEED_MEM) {
p=calloc((sizeof (int)),5);
}
...
...
free(p); // No problem here... [Remember that there is nothing wrong in freeing NULL memory; free call would return without doing anything]

No comments:

Post a Comment