We will talk of calloc, malloc, free and realloc.
To use the four functions discussed in this section, you must include the
stdlib.h header file.
Malloc and Free
#include
#include /* required for the malloc and free functions */
int main() {
int number;
int *ptr;
int i;
printf("How many ints would you like store? ");
scanf("%d", &number);
ptr = malloc(number*sizeof(int)); /* allocate memory */
if(ptr!=NULL) {
for(i=0 ; i
*(ptr+i) = i;
}
for(i=number ; i>0 ; i--) {
printf("%d\n", *(ptr+(i-1))); /* print out in reverse order */
}
free(ptr); /* free allocated memory */
return 0;
}
else {
printf("\nMemory allocation failed - not enough memory.\n");
return 1;
}
}
Calloc
Calloc is similar to
malloc, but the main difference is that the values stored in the allocated memory space is zero by default. With
malloc, the allocated memory could have any value.
calloc requires two arguments. The first is the number of variables you'd like to allocate memory for. The second is the size of each variable.
Like
malloc,
calloc will return a
void pointer if the memory allocation was successful, else it'll return a NULL pointer.
This example shows you how to call
calloc and also how to reference the allocated memory using an array index. The initial value of the allocated memory is printed out in the
for loop.
int main()
{
float *calloc1, *calloc2, *malloc1, *malloc2;
int i;
calloc1 = calloc(3, sizeof(float));
/* might need to cast */
calloc2 = calloc(3, sizeof(float));
malloc1 = malloc(3 * sizeof(float));
malloc2 = malloc(3 * sizeof(float));
if(calloc1!=NULL && calloc2!=NULL && malloc1!=NULL && malloc2!=NULL)
{
for(i=0 ; i<3 ; i++)
{
printf("calloc1[%d] holds %05.5f, ", i, calloc1[i]);
printf("malloc1[%d] holds %05.5f\n", i, malloc1[i]);
printf("calloc2[%d] holds %05.5f, ", i, *(calloc2+i));
printf("malloc2[%d] holds %05.5f\n", i, *(malloc2+i)); }
free(calloc1); free(calloc2); free(malloc1); free(malloc2);
return 0;
}
else
{ printf("Not enough memory\n"); return 1; }
}
Output:
calloc1[0] holds 0.00000, malloc1[0] holds -431602080.00000
calloc2[0] holds 0.00000, malloc2[0] holds -431602080.00000
calloc1[1] holds 0.00000, malloc1[1] holds -431602080.00000
calloc2[1] holds 0.00000, malloc2[1] holds -431602080.00000
calloc1[2] holds 0.00000, malloc1[2] holds -431602080.00000
calloc2[2] holds 0.00000, malloc2[2] holds -431602080.00000 |
realloc
Now suppose you've allocated a certain number of bytes for an array but later find that you want to add values to it. You could copy everything into a larger array, which is inefficient, or you can allocate more bytes using
realloc, without losing your data.
realloc takes two arguments. The first is the pointer referencing the memory. The second is the total number of bytes you want to reallocate.
Passing zero as the second argument is the equivalent of calling
free.
Once again,
realloc returns a
void pointer if successful, else a NULL pointer is returned.
This example uses
calloc to allocate enough memory for an
int array of five elements. Then
realloc is called to extend the array to hold seven elements.
#include
#include
int main() {
int *ptr;
int i;
ptr = calloc(5, sizeof(int));
if(ptr!=NULL) {
*ptr = 1;
*(ptr+1) = 2;
ptr[2] = 4;
ptr[3] = 8;
ptr[4] = 16;
/* ptr[5] = 32; wouldn't assign anything */
ptr = realloc(ptr, 7*sizeof(int));
if(ptr!=NULL) {
printf("Now allocating more memory... \n");
ptr[5] = 32; /* now it's legal! */
ptr[6] = 64;
for(i=0 ; i<7 ; i++) {
printf("ptr[%d] holds %d\n", i, ptr[i]);
}
realloc(ptr,0); /* same as free(ptr); - just fancier! */
return 0;
}
else {
printf("Not enough memory - realloc failed.\n");
return 1;
}
}
else {
printf("Not enough memory - calloc failed.\n");
return 1;
}
}
Output:
Now allocating more memory...
ptr[0] holds 1
ptr[1] holds 2
ptr[2] holds 4
ptr[3] holds 8
ptr[4] holds 16
ptr[5] holds 32
ptr[6] holds 64 |
Notice the two different methods I used when initializing the array:
ptr[2] = 4; is the equivalent to
*(ptr+2) = 4; (just easier to read!).
Before using
realloc, assigning a value to
ptr[5] wouldn't cause a compile error. The program would still run, but
ptr[5] wouldn't hold the value you assigned.