Выделение памяти только для одного элемента массива

Я не могу определить размер массива во время выполнения, потому что он будет иметь зависимости. Поэтому мне нужно выделить память для элемента. Я могу сказать, как и связанные списки.

Как я могу сделать это в целочисленных массивах?

вы не можете в массиве все элементы размещаются вместе

Tyker 16.05.2018 11:21

Привет, я добавил пару примечаний к своему ответу, который может оказаться полезным при перенаправлении указателей в перемещенный массив. Может быть неактуальным.

Persixty 16.05.2018 18:35

@Persixty спасибо за информацию. Они мне очень помогли.

drh0use 18.05.2018 10:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
519
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы говорите, что хотите «наращивать» массив по одному элементу за раз.

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 или требовать дополнительных усилий.

Другие вопросы по теме