The three things you want to check in order to reallocate memory for a pointer are:
- whether the prior allocation limit is reached;
- the new allocation size is greater than current; and
- that the call to
realloc
returns a valid pointer.
The last being the most informative. realloc
returns a pointer to the newly allocated memory if successful, or NULL
on failure. This has critical consequences for your existing data. If you attempt to realloc
using the existing pointer and it fails, your pointer is set to NULL
and your existing data is lost. That is why it is recommended to assign the return from realloc
to a temporary pointer and test that a valid pointer is returned before assigning the return of realloc
to your existing pointer.
The general approach to reallocation is to allocate a reasonable amount of memory to begin with. As memory is used, check whether the memory limit is reached. When reached realloc
two times the current amount of memory to a temporary pointer and check whether a valid pointer is retured. If so, assign the new pointer to your existing pointer and update the variable you are using to track the current allocation size. (repeat as necessary)
The following incorporates each of the above. Look it over and let me know if you have questions:
#include <stdio.h>
#include <stdlib.h>
#define MAXS 5
int main() {
int *myarray = NULL; /* initialize all variables */
int *tmp = NULL;
int asize = MAXS;
int i = 0;
printf ("\n Filling myarray with 30 elements (allocated 5)\n\n");
myarray = calloc (MAXS, sizeof *myarray); /* allocate 5 ints */
if (!myarray)
{
printf (" error: allocation failed.\n");
exit (EXIT_FAILURE);
}
for (i = 0; i < 30; i++) /* fill w/30 ints */
{
if (i == asize) /* test if at limit */
{ /* if so realloc */
if ((tmp = realloc (myarray, 2 * asize * sizeof *myarray)))
{
myarray = tmp; /* if OK, reassign */
asize = 2 * asize; /* update asize */
printf (" => reallocated myarray, size : %d\n", asize);
}
else /* realloc failed */
{
printf (" error: realloc failed.\n");
break;
}
}
myarray[i] = i; /* assign element */
printf (" filled myarray[%2d] : %d\n", i, myarray[i]);
}
if (myarray) free (myarray); /* free memory */
printf ("\n");
return 0;
}
output:
$ ./bin/reallocint
Filling myarray with 30 elements (allocated 5)
filled myarray[ 0] : 0
filled myarray[ 1] : 1
filled myarray[ 2] : 2
filled myarray[ 3] : 3
filled myarray[ 4] : 4
=> reallocated myarray, size : 10
filled myarray[ 5] : 5
filled myarray[ 6] : 6
filled myarray[ 7] : 7
filled myarray[ 8] : 8
filled myarray[ 9] : 9
=> reallocated myarray, size : 20
filled myarray[10] : 10
filled myarray[11] : 11
filled myarray[12] : 12
filled myarray[13] : 13
filled myarray[14] : 14
filled myarray[15] : 15
filled myarray[16] : 16
filled myarray[17] : 17
filled myarray[18] : 18
filled myarray[19] : 19
=> reallocated myarray, size : 40
filled myarray[20] : 20
filled myarray[21] : 21
filled myarray[22] : 22
filled myarray[23] : 23
filled myarray[24] : 24
filled myarray[25] : 25
filled myarray[26] : 26
filled myarray[27] : 27
filled myarray[28] : 28
filled myarray[29] : 29