Below I have a function trim()
. Which removes the leading zeros from an array of ints. It returns a pointer, which it receives from malloc()
. While running a loop of successive calls to trim()
and free()
. I noticed that the value returned by trim()
- which was received by malloc()
, is identical on every iteration.
It is my understanding that freeing the same pointer twice, if it is not NULL
, will result in a double free error. Why is a double free error not encountered in this situation?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, length;
int n[] = { 4, 5, 6 };
int m[] = { 0, 3, 5 };
int *num;
int *trimmed, *trimmed_length;
trimmed_length = &length;
for (i = 0; i < 10; i++)
{
num = (i % 2 == 0) ? n : m;
trimmed = trim(num, 3, trimmed_length);
if (!trimmed)
{
printf("trimmed was null\n");
exit(-1);
}
for (j = 0; j < *trimmed_length; j++)
{
printf("%d", trimmed[j]);
}
printf("\n");
free(trimmed);
}
exit(0);
}
int *trim(int *n, int nlength, int *res_length)
{
int i, j;
int *res;
for (i = 0; i < nlength; i++)
{
if (n[i] > 0)
{
break;
}
}
*res_length = (nlength - i);
res = malloc(sizeof(int) * (*res_length));
if (!res)
{
return NULL;
}
j = 0;
while (i < nlength)
{
res[j++] = n[i++];
}
printf("Returned pointer from trim() %d\n", res);
return res;
}
Output:
Returned pointer from trim() 11759632
456
Returned pointer from trim() 11759632
35
Returned pointer from trim() 11759632
456
Returned pointer from trim() 11759632
35
Returned pointer from trim() 11759632
456
Returned pointer from trim() 11759632
35
Returned pointer from trim() 11759632
456
Returned pointer from trim() 11759632
35
Returned pointer from trim() 11759632
456
Returned pointer from trim() 11759632
35
What you're seeing is not a double free. Consider:
void *p1, *p2;
p1 = malloc(10);
free(p1);
p2 = malloc(10);
At this point there's no guarantee that p1 and p2 are the same. There's no guarantee they're different. If they happen to be the same, calling free(p2)
at this point is not a double free. The following would be an actual double free:
void *p = malloc(10);
free(p);
free(p);