You could use a combination of malloc()
(or calloc()
), realloc()
and free()
to achieve this.
Memory can be allocated as blocks of a fixed size rather than reallocating memory for each number to be stored.
Let's define a macro (or a const
if you like) BLOCK_SIZE
.
#define BLOCK_SIZE 10
First declare a pointer of appropriate type and allocate the first block.
Note that malloc()
as well as realloc()
return NULL
if some error occurred due to reasons like insufficient memory.
int *ptr=malloc(sizeof(int)*BLOCK_SIZE);
if(ptr==NULL)
{
perror("some error");
return 1;
}
Now declare a variable to store the maximum possible index as per the currently allocated memory (to avoid illegal memory access).
int max_index = BLOCK_SIZE-1;
Now use a loop.
for(int i=0; ; ++i)
{
if(i > max_index)
{
ptr=realloc(ptr, (max_index+1 + BLOCK_SIZE)*sizeof(int));
if(ptr == NULL)
{
perror("insufficient memory!");
break;
}
printf("\nRealloced!");
max_index += BLOCK_SIZE;
}
scanf("%d", &ptr[i]);
printf("\n%d: %d", i, ptr[i]);
}
In each iteration, we check if i
is greater than max_index
. If it is, another block is allocated using realloc()
before reading the value.
Don't forget to deallocate the memory once you are done using it.
free(ptr);
Also, as discussed in this post, malloc()
is effectively the same as realloc()
with the latter's first argument NULL
.
And in the code you posted, there's no need to explicitly cast the return value of calloc()
as what's returned is a void
pointer which would implicitly be converted to the target pointer type.
See this and this.