I encountered something odd when freeing the memory in a two dimensional array after something goes wrong.
Case 1:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main(void)
{
int **a = NULL;
int i;
int j;
if(!(a = calloc(5, sizeof(int *))))
{
printf("Error, could not allocate memory for a!\n");
exit(EXIT_FAILURE);
}
for(i = 0; i < 5; i++)
{
if(i != 2)
{
if(!(a[i] = calloc(3, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]!\n",i);
for(j = 0; j < i; j++)
{
free(a[j]);
}
free(a);
}
}
else
{
if(!(a[i] = calloc(MAX_INT * 1000, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]\n", i);
for(j = 0; j < i; j++)
{
free(a[j]);
}
free(a);
}
}
}
return 0;
}
Case 2:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main(void)
{
int **a = NULL;
int i;
int j;
if(!(a = calloc(5, sizeof(int *))))
{
printf("Error, could not allocate memory for a!\n");
exit(EXIT_FAILURE);
}
for(i = 0; i < 5; i++)
{
if(i != 2)
{
if(!(a[i] = calloc(3, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]!\n",i);
for(j = 0; j <= i; j++)
{
free(a[j]);
}
free(a);
}
}
else
{
if(!(a[i] = calloc(MAX_INT * 1000, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]\n", i);
for(j = 0; j <= i; j++)
{
free(a[j]);
}
free(a);
}
}
}
return 0;
}
The only difference between the two cases is that in case 1, when something goes wrong allocating memory (I deliberately have a large allocation to cause it to fail when i == 2) I loop from j = 0 to j < i and in case 2 I loop from j = 0 to j <= i when freeing the a[j]. Neither gives me a compiler error or warning and neither results in a problem or leak when run through valgrind, so I was just wondering which was the correct way to do it? I thought it was case 1 because the allocation of element i failed, and so no memory is actually allocated, which means there's no need to free it, but the lack of a leak from valgrind has me second guessing myself. Thanks!