Я не могу определить размер массива во время выполнения, потому что он будет иметь зависимости. Поэтому мне нужно выделить память для элемента. Я могу сказать, как и связанные списки.
Как я могу сделать это в целочисленных массивах?
Привет, я добавил пару примечаний к своему ответу, который может оказаться полезным при перенаправлении указателей в перемещенный массив. Может быть неактуальным.
@Persixty спасибо за информацию. Они мне очень помогли.





Я думаю, вы говорите, что хотите «наращивать» массив по одному элементу за раз.
realloc() - это опция в C для массива целых чисел (*).
size_t n=0;//Length of array.
int* arr=NULL;
//Some code...
//Now we want to grow our array
//This is probably in a loop or called in a function from a loop (not shown).
++n;
int* temp=realloc(arr,n*sizeof(int));
if (temp==NULL){
free(arr);
return 1;//Error...
}
arr=temp;
//More code....
//Now we're done with arr.
free(arr);
В первом проходе arr - это NULL, а realloc(NULL,..) действует как malloc().
Но в последующих проходах, когда arr не является NULL, тогда realloc пытается увеличить массив «на месте» (если в конце есть доступная память). В противном случае он пытается выделить место в другом месте, а затем копирует существующие данные и освобождает старое место.
Если перераспределить не удается, он ничего не делает и возвращает NULL, поэтому вы несете ответственность за последующее освобождение этого пространства (free(arr)).
NB: всегда выделяйте возврат realloc() временной переменной (т.е. не первому аргументу).
В противном случае, если выделение не удалось, значит произошла утечка существующей памяти.
realloc - это быстрый способ уменьшить объем выделения и копирования, необходимый для увеличения массива - альтернатива.
Если это недостаточно эффективно, обычная модель должна отслеживать «вместимость» и «длину» примерно так.
const size_t chunk=10;
size_t cap=0;
size_t n=0;
int* arr=NULL;
++n;
if (n>cap){
cap+=chunk;
int* temp=realloc(arr,cap);
if (temp==NULL){
free(arr);
return 1;//Error
}
}
//Later...
free(arr);
Это дает вам преимущество в том, что вы можете настроить, сколько «лишних» накладных расходов вы должны настроить, чтобы настроить частоту перераспределения. Другая стратегия - cap=cap*2;, хотя очевидно, что пространство имеет тенденцию к экспоненциальному росту! Можно написать книгу о стратегиях для этого классика. Часто можно выделить достаточно для наиболее реалистичных случаев за одно обращение, но все же можно обработать исключительные случаи.
У вас также есть возможность выделить обратно для восстановления свободного пространства, если вы знаете, что массив теперь полноразмерный.
Если это не очевидно, если массив перемещается, любые указатели на него или в него должны быть перенаправлены. Это аргумент в пользу индексации только с помощью [.]. Вам нужно будет удерживать старое местоположение, пока вы не выполните перенаправление. ptr=temp+(ptr-arr) указывает ptr на новое местоположение элемента, на который указывает ptr.
Это стандартный подход, встречающийся в Java ArrayList и большинстве реализаций std::vector<>. Это инженерный компромисс. Преимущества массива (O (1) произвольный доступ по индексу) и связанного списка (рост O (1)).
Асимптотически он остается линейным, но в практических случаях дает большие преимущества. Информатика занимается асимптотическими скоростями и разработкой с фактическими значениями в конечных реальных случаях.
(*) Копия - это необработанная копия памяти. Это нормально для int, но сложные структуры «struct» могут быть недоступны для копирования в memmove или требовать дополнительных усилий.
вы не можете в массиве все элементы размещаются вместе