Для этого можно использовать комбинацию malloc()
(или calloc()
), realloc()
и free()
.
Память может быть выделена как блоки фиксированного размера, а не перераспределять память для каждого сохраняемого числа.
Давайте определим макрос (или const
, если хотите) BLOCK_SIZE
.
#define BLOCK_SIZE 10
Сначала объявите указатель соответствующего типа и выделите первый блок.
Обратите внимание, что malloc()
, а также realloc()
возвращают NULL
, если произошла какая-либо ошибка по причинам, таким как нехватка памяти.
int *ptr=malloc(sizeof(int)*BLOCK_SIZE);
if(ptr==NULL)
{
perror("some error");
return 1;
}
Теперь объявите переменную для хранения максимально возможного индекса в соответствии с выделенной в данный момент памятью (чтобы избежать несанкционированного доступа к памяти).
int max_index = BLOCK_SIZE-1;
Теперь используйте цикл.
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]);
}
На каждой итерации мы проверяем, больше ли i
, чем max_index
. Если это так, другой блок выделяется с помощью realloc()
перед чтением значения.
Не забудьте освободить память, как только закончите с ней.
free(ptr);
Кроме того, как обсуждалось в этом посте, malloc()
фактически совпадает с realloc()
с первым аргументом последнего NULL
.
И в опубликованном вами коде нет необходимости явно приводить возвращаемое значение calloc()
, поскольку возвращаемым является указатель void
, который неявно преобразуется в целевой тип указателя.
См. это и это .