Динамический массив
Динамическим называется массив, размер которого может изменяться во время исполнения программы. Возможность изменения размера отличает динамический массив от статического, размер которого задаётся на момент компиляции программы. Для изменения размера динамического массива язык программирования, поддерживающий такие массивы, должен предоставлять встроенную функцию или оператор. Динамические массивы дают возможность более гибкой работы с данными, так как позволяют не прогнозировать хранимые объёмы данных, а регулировать размер массива в соответствии с реально необходимыми объёмами.

Также иногда к динамическим относят массивы переменной длины, размер которых не фиксируется при компиляции, а задаётся при создании или инициализации массива во время исполнения программы. От «настоящих» динамических массивов они отличаются тем, что для них не предоставляются средства автоматического изменения размера с сохранением содержимого, так что при необходимости программист должен реализовать такие средства самостоятельно.
Поддержка в языках программирования
Динамические массивы могут поддерживаться либо на уровне синтаксиса самого языка программирования, либо на уровне системных библиотек. Описание динамического массива может синтаксически отличаться от описания статического, но может и быть таким же. Во втором случае, как правило, все массивы в языке являются потенциально динамическими, и только от программиста зависит, использовать ли это свойство в каждом конкретном случае. При поддержке динамических массивов посредством системных библиотек они обычно реализуются в виде классов (в смысле ООП) или обобщённых типов (так называемых «шаблонов» или «дженериков»); описание массива в этом случае представляет собой инстанцирование класса или конкретизацию обобщённого типа. В зависимости от языка, динамические массивы могут быть только одномерными массивами или иметь размерность два и более.
Поддержка динамических массивов предполагает обязательное наличие встроенной операции определения текущего размера массива. Первоначальный размер динамического массива либо равен нулю, либо задаётся при описании или инициализации. Дальнейшие изменения размера выполняются специальной встроенной операцией (процедурой). В некоторых языках (например, JavaScript, Lua) расширение массива происходит автоматически, когда делается попытка записи в несуществующую ячейку.
Реализация
Для массивов с возможностью динамического изменения размера при реализации приходится находить «золотую середину» между несколькими противоречивыми требованиями.
- Эффективность по памяти — реализация не должна приводить к существенному перерасходу памяти.
- Эффективность по производительности, которая включает в себя:
- минимальные накладные расходы на изменение размера массива;
- сохранение, по возможности, константного времени доступа на чтение/запись к элементам массива.
- Совместимость с обычными статическими массивами на низком уровне. Например, необходимым условием для применения динамического массива в вызовах функций API операционной системы может быть обязательное размещение элементов массива в непрерывном блоке физической оперативной памяти в порядке, соответствующем индексации массива. Если такое требование не выполняется, динамические массивы окажется невозможно использовать в сочетании с низкоуровневым кодом.
В зависимости от приоритета тех или иных требований выбирается отвечающий им способ реализации.
Массивы переменной длины
Реализация массивов переменной длины мало отличается от реализации обычных статических массивов. Массив элементов типа T переменной длины обычно хранится в непрерывном блоке оперативной памяти размером , где N — число элементов, указываемое при описании (создании) массива. То есть описание массива переменной длины, фактически, просто маскирует динамическое выделение памяти. Разница может состоять в том, что (например, как в Си стандарта C99 и позже) массиву переменной длины выделяется память на стеке, как другим автоматическим переменным, в то время как типовой способ динамического выделения памяти (в Си — функция
malloc) выделяет память в куче. Кроме того, для массива переменной длины компилятор, как правило, автоматически генерирует код освобождения памяти при выходе объявленного массива из области видимости.
Перемещение массива в памяти
Наиболее распространённой для типичных процедурных компилируемых языков является реализация изменения размера массива путём перемещения его в динамической памяти.
- Под массив выделяется фрагмент ОЗУ, размер которого больше требуемого т. н. логического размера (size или length). Количество элементов, которое фактически может быть размещено в этой памяти, называется ёмкостью (capacity) динамического массива. Текущая длина массива хранится в отдельном счётчике. Она может использоваться для определения текущего размера, а также для контроля выхода за границы массива, если язык поддерживает такой контроль. Таким образом, в действительности динамический массив — это массив фиксированного размера, в котором занята только часть ячеек.
- Команда увеличения размера массива, если новый размер не превышает ёмкости, просто изменяет счётчик длины массива до нужного размера. С самим массивом никаких изменений при этом не происходит.
- Команда увеличения размера, в которой новый размер превышает ёмкость, приводит к перемещению массива в памяти:
- выделяется новый фрагмент ОЗУ, размер которого превышает размер массива;
- содержимое массива копируется во вновь выделенную память;
- размер и ёмкость массива актуализируются;
- в служебной структуре, хранящей параметры массива, значение указателя на данные меняется на новое;
- запускается команда освобождения ранее выделенного под массив фрагмент ОЗУ; если язык поддерживает автоматическое управление памятью, то освобождение ранее выделенной под массив памяти остаётся за сборщиком мусора.
- Команда уменьшения размера массива может приводить к перемещению его в памяти, если в результате её выполнения процент занятых ячеек в массиве падает ниже определённого значения. Перемещение при этом проводится по той же схеме, что и в случае команды увеличения массива.
Данная реализация является наиболее эффективной по скорости доступа к уже выделенным ячейкам массива. Кроме того, она обеспечивает константное время доступа к любому элементу, независимо от его индекса. Однако дополнительные накладные расходы на операции изменения размера могут оказаться значительными. Величина этих расходов зависит от параметров алгоритма перемещения массива.
- Начальная ёмкость и приращение ёмкости при увеличении размера. Может задаваться либо относительной величиной (определённая доля от логической длины массива), либо абсолютным приращением сверх требуемой длины массива. Чем больше эти параметры, тем позже, при том же режиме заполнения массива, потребуется следующее перемещение, но и тем больше памяти потенциально останется неиспользуемой. Расширение массива на любой постоянный коэффициент гарантирует, что вставка n-элементов займет O(n) времени, это означает, что каждая вставка занимает конкретное, определённое время. Численное значение этого коэффициента приводит к разным показателям: среднее время вставки операции составляет a/(a-1), в то время как число потраченных впустую ячеек составляет (a-1)n. Значение этой константы в различных приложениях и библиотеках может быть разным: во многих учебниках используют значение 2, но в реализации ArrayList языка Java используется коэффициент 3/2, в некоторых других случаях используют a=9/8.
- Минимальная ёмкость. Обычно задаётся из соображений эффективности, чтобы не терять производительность при частых изменениях размеров небольших массивов. Практически её установка означает, что все динамические массивы размером менее минимальной ёмкости в действительности будут терять память.
- Процент минимального заполнения массива. Определяет, когда будет происходить перемещение после сокращения размера массива. Чем больше эта величина, тем чаще при уменьшении размера массива будет происходить перемещение. Чем она меньше, тем больше памяти при уменьшении размера массива будет оставаться занятой, но не используемой.
Существуют различные оценки оптимальных величин для параметров алгоритма перемещения, но из общих соображений ясно, что ни один из способов их определения не гарантирует максимальной эффективности во всех случаях и для любого можно подобрать алгоритм работы с массивом, при котором перемещение будет неэффективным. Для компенсации негативных эффектов многие языки, поддерживающие динамические массивы, в командах увеличения/уменьшения массива имеют дополнительные параметры, позволяющие прямо управлять ёмкостью массива. Если программист заведомо знает, до каких размеров увеличится/уменьшится массив в результате той или иной операции, и как в дальнейшем будет происходить работа с массивом, он имеет возможность прямо указать требуемую конечную ёмкость в команде изменения размера, избежав таким образом большого количества бессмысленных перемещений.
Другие динамические алгоритмы размещения
Существует множество алгоритмов реализации динамических массивов, кроме вышеописанного. Так, возможна реализация с помощью динамических ячеек памяти, связанных ссылками, других различных структур данных. Большинство таких методов обеспечивают преимущество в каких-то определённых условиях, но либо не обеспечивает константного времени доступа, либо несовместимо со статическими массивами и поэтому не может работать с низкоуровневым кодом.
Использование
Динамические массивы используются для обработки наборов однородных данных, размер которых не известен точно на момент написания программы, но которые потенциально могут разместиться в доступной памяти. Без использования динамических массивов решение таких задач сводится к одной из стратегий:
- выделение статического массива большого размера, заведомо достаточного для полного размещения данных;
- использование статического массива в качестве буфера, в который данные загружаются частями;
- применение иных динамических структур данных (например, списков).
Первый вариант применим только когда размер набора данных меняется в небольшом, жёстко ограниченном диапазоне (например, в текстовой обработке ограничение в 1000 знаков на строку вполне приемлемо). В противном случае выбор маленького массива будет ограничивать функциональность программы, а большого (так, чтобы заведомо хватило для любых входных данных) приведёт к неэффективному расходованию памяти. Буферизация обработки усложняет алгоритм, а другие динамические структуры в задачах обработки больших последовательностей простых данных по эффективности не могут сравниться с массивом.
Использование динамических массивов позволяет выделить ровно столько памяти, сколько реально необходимо (сразу, если задача позволяет определить объём до загрузки данных, либо в процессе загрузки, расширяя массив по мере необходимости), загрузить все данные в один массив и единообразно их обработать. Недостатки, однако, имеются и у этой стратегии:
- снижение скорости работы из-за накладных расходов на изменение размера динамического массива;
- потенциальное снижение надёжности: при экстремально большом объёме входных данных попытка увеличить массив до соответствующих размеров может привести к внезапному существенному замедлению или даже отказу программы из-за недостатка свободной памяти.
В целом можно заметить, что поддержка динамических массивов повышает удобство разработки, но не освобождает программиста от необходимости проводить оценку потребностей программы в памяти; также она требует понимания особенностей конкретной реализации динамических массивов и согласования алгоритмов обработки данных с этими особенностями.
Примеры
Паскаль
Динамические массивы поддерживаются Delphi, FreePascal, но не Turbo Pascal.
var byteArray : Array of Byte; // Одномерный массив multiArray : Array of Array of string; // Многомерный массив ... begin ... // Установить размер одномерного массива в n элементов SetLength (byteArray, n); // Доступ к динамическому массиву аналогичен доступу к обычному. // Индексация всегда начинается с нуля, индексы - всегда целые. byteArray[0] := 10; // Изменить размер до m элементов. SetLength(byteArray, m); ... // Установить размер двумерного массива в X*Y элементов SetLength(multiArray, X, Y); multiArray[7,35] := 'ru.wikipedia.org'; ... end. Си
В самом языке Си нет динамических массивов, но функции стандартной библиотеки malloc, free и realloc позволяют реализовать массив переменного размера:
int *mas = (int*)malloc(sizeof(int) * n); // Создание массива из n элементов типа int ... mas = (int*)realloc(mas, sizeof(int) * m); // Изменение размера массива с n на m с сохранением содержимого ... free(mas); // Освобождение памяти после использования массива Неудобство данного подхода состоит в необходимости вычислять размеры выделяемой памяти, применять явное преобразование типа и тщательно отслеживать время жизни массива (как и всегда при работе с динамически выделенной памятью в Си).
Многомерный динамический массив может быть создан как массив указателей на массивы:
int **A = (int **)malloc(N*sizeof(int *)); for(int i = 0; i < N; i++) { A[i] = (int *)malloc(M*sizeof(int)); } Однако рост размерности существенно усложняет процедуры создания массива и освобождения памяти по завершении его использования. Ещё более усложняется задача изменения размера массива по одной или нескольким координатам.
Некоторые компиляторы Си предоставляют нестандартную библиотечную функцию void *alloca(size_t size), несколько упрощающую работу с динамическими массивами. Эта функция выделяет память не в куче, как malloc, а на стеке, и эта память автоматически освобождается при достижении оператора return. То есть при выделении памяти динамического массива этой функцией его не нужно удалять вручную, но такой массив невозможно вернуть из функции в точку вызова.
Начиная с версии стандарта C99 в язык введены массивы переменной длины. В обычном синтаксисе описания массива Си на месте размера массива может указываться не только константа, но и переменная целого типа:
void func(int arraySize) { int mas[arraySize]; // Описание массива переменной длины for (int i = 0; i < arraySize; ++i) { mas[i] = anotherFunc(i); // Обращение к элементам массива } ... } Массив переменной длины может получить любой необходимый размер в момент создания. Память под него выделяется на стеке. Массив переменной длины существует до выхода из области видимости, в которой он был объявлен, после чего его память автоматически освобождается. Как и в предыдущем случае, массив переменной длины невозможно вернуть из функции в точку вызова.
C++
В стандартной библиотеке предусмотрен шаблонный класс std::vector, реализующий функциональность динамического массива:
// Объявляем массив mas, изначально содержащий числа 1 - 5: std::vector<int> mas = {1, 2, 3, 4, 5}; mas.reserve(100); // Зарезервировать место для хранения не менее 100 элементов, не изменяя фактический размер. Содержимое остаётся прежним. mas.resize(50); // Задать явный размер - ровно 50 элементов. Недостающие элементы получат значение "по умолчанию", лишние элементы будут удалены. mas[i] = i; // Присвоить i'му элементу значение i mas.push_back(100); // Добавить элемент в конец массива int x = mas.back(); // Обращение к последнему элементу, в данном примере x == 100 mas.pop_back(); // Удалить последний элемент std::cout << mas.size() << " " << mas.capacity() << "\n"; // Вывести ёмкость и фактический размер auto mas2 = mas; // Переменная mas2 содержит полную копию mas std::vector имеет множество методов и операторов, часть из которых показана выше на примере. Они позволяют обращаться по индексу, изменять в любую сторону размер массива, использовать его как стек, записывать новое значение в произвольную позицию массива(со сдвигом остальных элементов), и вообще поддерживать семантику [англ.] : копировать, обменивать, перемещать, передавать в функции и возвращать, поэлементно сравнивать с другим объектом того же типа. Управляемым является не только актуальный размер, но и ёмкость, что позволяет оптимизировать процесс выделения памяти.
std::vector реализует принцип RAII: владеет своими подобъектами, выделяет и освобождает память и правильно вызывает конструкторы/деструкторы.
Стандарт C++ требует от реализации обязательного выполнения условий:
- все элементы массива должны храниться подряд в порядке увеличения индекса в целостном блоке оперативной памяти;
- должно быть гарантировано константное время доступа к произвольному элементу.
Низкоуровневая работа с динамической памятью может реализовываться средствами, унаследованными от языка-предка, но для обеспечения типобезопасности и соблюдения требований объектной модели память под массивы рекомендуется выделять посредством специфичных для языка операторов new [] и delete []:
// Выделение памяти под массив int длиной n int *mas = new int [n]; ... // Освобождение памяти массива delete [] mas; Помимо прочего, это позволяет переопределять операторы new [] и delete [] для пользовательских типов и таким образом реализовывать собственные схемы распределения памяти.
В современном C++ ручное управление памятью является неотъемлемым фундаментом для реализации шаблонных контейнеров, однако представляет значительные трудности даже для опытных программистов, и не рекомендуется к использованию в прикладном коде.
Примечания
- std::vector - cppreference.com. Дата обращения: 16 октября 2021. Архивировано 28 июня 2011 года.
- C++ Core Guidelines: R.1: Manage resources automatically using resource handles and RAII (Resource Acquisition Is Initialization). Дата обращения: 16 октября 2021. Архивировано 8 февраля 2020 года.
- C++ Core Guidelines: R.11: Avoid calling new and delete explicitly. Дата обращения: 16 октября 2021. Архивировано 8 февраля 2020 года.
У этой статьи по информационным технологиям есть несколько проблем, помогите их исправить: |
Википедия, чтение, книга, библиотека, поиск, нажмите, истории, книги, статьи, wikipedia, учить, информация, история, скачать, скачать бесплатно, mp3, видео, mp4, 3gp, jpg, jpeg, gif, png, картинка, музыка, песня, фильм, игра, игры, мобильный, телефон, Android, iOS, apple, мобильный телефон, Samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Сеть, компьютер, Информация о Динамический массив, Что такое Динамический массив? Что означает Динамический массив?
Dinamicheskim nazyvaetsya massiv razmer kotorogo mozhet izmenyatsya vo vremya ispolneniya programmy Vozmozhnost izmeneniya razmera otlichaet dinamicheskij massiv ot staticheskogo razmer kotorogo zadayotsya na moment kompilyacii programmy Dlya izmeneniya razmera dinamicheskogo massiva yazyk programmirovaniya podderzhivayushij takie massivy dolzhen predostavlyat vstroennuyu funkciyu ili operator Dinamicheskie massivy dayut vozmozhnost bolee gibkoj raboty s dannymi tak kak pozvolyayut ne prognozirovat hranimye obyomy dannyh a regulirovat razmer massiva v sootvetstvii s realno neobhodimymi obyomami Uvelichenie razmera massiva proishodit bystro poka on menshe obyoma massiva Kogda nuzhno uvelichit razmer massiva a svobodnogo mesta v nyom net sozdayotsya eshyo odin massiv bolshego obyoma vse elementy starogo obyoma kopiruyutsya v novyj massiv ssylka na staryj massiv udalyaetsya Na kartinke pomecheno cherepahami Takzhe inogda k dinamicheskim otnosyat massivy peremennoj dliny razmer kotoryh ne fiksiruetsya pri kompilyacii a zadayotsya pri sozdanii ili inicializacii massiva vo vremya ispolneniya programmy Ot nastoyashih dinamicheskih massivov oni otlichayutsya tem chto dlya nih ne predostavlyayutsya sredstva avtomaticheskogo izmeneniya razmera s sohraneniem soderzhimogo tak chto pri neobhodimosti programmist dolzhen realizovat takie sredstva samostoyatelno Podderzhka v yazykah programmirovaniyaDinamicheskie massivy mogut podderzhivatsya libo na urovne sintaksisa samogo yazyka programmirovaniya libo na urovne sistemnyh bibliotek Opisanie dinamicheskogo massiva mozhet sintaksicheski otlichatsya ot opisaniya staticheskogo no mozhet i byt takim zhe Vo vtorom sluchae kak pravilo vse massivy v yazyke yavlyayutsya potencialno dinamicheskimi i tolko ot programmista zavisit ispolzovat li eto svojstvo v kazhdom konkretnom sluchae Pri podderzhke dinamicheskih massivov posredstvom sistemnyh bibliotek oni obychno realizuyutsya v vide klassov v smysle OOP ili obobshyonnyh tipov tak nazyvaemyh shablonov ili dzhenerikov opisanie massiva v etom sluchae predstavlyaet soboj instancirovanie klassa ili konkretizaciyu obobshyonnogo tipa V zavisimosti ot yazyka dinamicheskie massivy mogut byt tolko odnomernymi massivami ili imet razmernost dva i bolee Podderzhka dinamicheskih massivov predpolagaet obyazatelnoe nalichie vstroennoj operacii opredeleniya tekushego razmera massiva Pervonachalnyj razmer dinamicheskogo massiva libo raven nulyu libo zadayotsya pri opisanii ili inicializacii Dalnejshie izmeneniya razmera vypolnyayutsya specialnoj vstroennoj operaciej proceduroj V nekotoryh yazykah naprimer JavaScript Lua rasshirenie massiva proishodit avtomaticheski kogda delaetsya popytka zapisi v nesushestvuyushuyu yachejku RealizaciyaDlya massivov s vozmozhnostyu dinamicheskogo izmeneniya razmera pri realizacii prihoditsya nahodit zolotuyu seredinu mezhdu neskolkimi protivorechivymi trebovaniyami Effektivnost po pamyati realizaciya ne dolzhna privodit k sushestvennomu pererashodu pamyati Effektivnost po proizvoditelnosti kotoraya vklyuchaet v sebya minimalnye nakladnye rashody na izmenenie razmera massiva sohranenie po vozmozhnosti konstantnogo vremeni dostupa na chtenie zapis k elementam massiva Sovmestimost s obychnymi staticheskimi massivami na nizkom urovne Naprimer neobhodimym usloviem dlya primeneniya dinamicheskogo massiva v vyzovah funkcij API operacionnoj sistemy mozhet byt obyazatelnoe razmeshenie elementov massiva v nepreryvnom bloke fizicheskoj operativnoj pamyati v poryadke sootvetstvuyushem indeksacii massiva Esli takoe trebovanie ne vypolnyaetsya dinamicheskie massivy okazhetsya nevozmozhno ispolzovat v sochetanii s nizkourovnevym kodom V zavisimosti ot prioriteta teh ili inyh trebovanij vybiraetsya otvechayushij im sposob realizacii Massivy peremennoj dliny Realizaciya massivov peremennoj dliny malo otlichaetsya ot realizacii obychnyh staticheskih massivov Massiv elementov tipa T peremennoj dliny obychno hranitsya v nepreryvnom bloke operativnoj pamyati razmerom sizeof T N displaystyle sizeof T cdot N gde N chislo elementov ukazyvaemoe pri opisanii sozdanii massiva To est opisanie massiva peremennoj dliny fakticheski prosto maskiruet dinamicheskoe vydelenie pamyati Raznica mozhet sostoyat v tom chto naprimer kak v Si standarta C99 i pozzhe massivu peremennoj dliny vydelyaetsya pamyat na steke kak drugim avtomaticheskim peremennym v to vremya kak tipovoj sposob dinamicheskogo vydeleniya pamyati v Si funkciya malloc vydelyaet pamyat v kuche Krome togo dlya massiva peremennoj dliny kompilyator kak pravilo avtomaticheski generiruet kod osvobozhdeniya pamyati pri vyhode obyavlennogo massiva iz oblasti vidimosti Peremeshenie massiva v pamyati Naibolee rasprostranyonnoj dlya tipichnyh procedurnyh kompiliruemyh yazykov yavlyaetsya realizaciya izmeneniya razmera massiva putyom peremesheniya ego v dinamicheskoj pamyati Pod massiv vydelyaetsya fragment OZU razmer kotorogo bolshe trebuemogo t n logicheskogo razmera size ili length Kolichestvo elementov kotoroe fakticheski mozhet byt razmesheno v etoj pamyati nazyvaetsya yomkostyu capacity dinamicheskogo massiva Tekushaya dlina massiva hranitsya v otdelnom schyotchike Ona mozhet ispolzovatsya dlya opredeleniya tekushego razmera a takzhe dlya kontrolya vyhoda za granicy massiva esli yazyk podderzhivaet takoj kontrol Takim obrazom v dejstvitelnosti dinamicheskij massiv eto massiv fiksirovannogo razmera v kotorom zanyata tolko chast yacheek Komanda uvelicheniya razmera massiva esli novyj razmer ne prevyshaet yomkosti prosto izmenyaet schyotchik dliny massiva do nuzhnogo razmera S samim massivom nikakih izmenenij pri etom ne proishodit Komanda uvelicheniya razmera v kotoroj novyj razmer prevyshaet yomkost privodit k peremesheniyu massiva v pamyati vydelyaetsya novyj fragment OZU razmer kotorogo prevyshaet razmer massiva soderzhimoe massiva kopiruetsya vo vnov vydelennuyu pamyat razmer i yomkost massiva aktualiziruyutsya v sluzhebnoj strukture hranyashej parametry massiva znachenie ukazatelya na dannye menyaetsya na novoe zapuskaetsya komanda osvobozhdeniya ranee vydelennogo pod massiv fragment OZU esli yazyk podderzhivaet avtomaticheskoe upravlenie pamyatyu to osvobozhdenie ranee vydelennoj pod massiv pamyati ostayotsya za sborshikom musora Komanda umensheniya razmera massiva mozhet privodit k peremesheniyu ego v pamyati esli v rezultate eyo vypolneniya procent zanyatyh yacheek v massive padaet nizhe opredelyonnogo znacheniya Peremeshenie pri etom provoditsya po toj zhe sheme chto i v sluchae komandy uvelicheniya massiva Dannaya realizaciya yavlyaetsya naibolee effektivnoj po skorosti dostupa k uzhe vydelennym yachejkam massiva Krome togo ona obespechivaet konstantnoe vremya dostupa k lyubomu elementu nezavisimo ot ego indeksa Odnako dopolnitelnye nakladnye rashody na operacii izmeneniya razmera mogut okazatsya znachitelnymi Velichina etih rashodov zavisit ot parametrov algoritma peremesheniya massiva Nachalnaya yomkost i prirashenie yomkosti pri uvelichenii razmera Mozhet zadavatsya libo otnositelnoj velichinoj opredelyonnaya dolya ot logicheskoj dliny massiva libo absolyutnym prirasheniem sverh trebuemoj dliny massiva Chem bolshe eti parametry tem pozzhe pri tom zhe rezhime zapolneniya massiva potrebuetsya sleduyushee peremeshenie no i tem bolshe pamyati potencialno ostanetsya neispolzuemoj Rasshirenie massiva na lyuboj postoyannyj koefficient garantiruet chto vstavka n elementov zajmet O n vremeni eto oznachaet chto kazhdaya vstavka zanimaet konkretnoe opredelyonnoe vremya Chislennoe znachenie etogo koefficienta privodit k raznym pokazatelyam srednee vremya vstavki operacii sostavlyaet a a 1 v to vremya kak chislo potrachennyh vpustuyu yacheek sostavlyaet a 1 n Znachenie etoj konstanty v razlichnyh prilozheniyah i bibliotekah mozhet byt raznym vo mnogih uchebnikah ispolzuyut znachenie 2 no v realizacii ArrayList yazyka Java ispolzuetsya koefficient 3 2 v nekotoryh drugih sluchayah ispolzuyut a 9 8 Minimalnaya yomkost Obychno zadayotsya iz soobrazhenij effektivnosti chtoby ne teryat proizvoditelnost pri chastyh izmeneniyah razmerov nebolshih massivov Prakticheski eyo ustanovka oznachaet chto vse dinamicheskie massivy razmerom menee minimalnoj yomkosti v dejstvitelnosti budut teryat pamyat Procent minimalnogo zapolneniya massiva Opredelyaet kogda budet proishodit peremeshenie posle sokrasheniya razmera massiva Chem bolshe eta velichina tem chashe pri umenshenii razmera massiva budet proishodit peremeshenie Chem ona menshe tem bolshe pamyati pri umenshenii razmera massiva budet ostavatsya zanyatoj no ne ispolzuemoj Sushestvuyut razlichnye ocenki optimalnyh velichin dlya parametrov algoritma peremesheniya no iz obshih soobrazhenij yasno chto ni odin iz sposobov ih opredeleniya ne garantiruet maksimalnoj effektivnosti vo vseh sluchayah i dlya lyubogo mozhno podobrat algoritm raboty s massivom pri kotorom peremeshenie budet neeffektivnym Dlya kompensacii negativnyh effektov mnogie yazyki podderzhivayushie dinamicheskie massivy v komandah uvelicheniya umensheniya massiva imeyut dopolnitelnye parametry pozvolyayushie pryamo upravlyat yomkostyu massiva Esli programmist zavedomo znaet do kakih razmerov uvelichitsya umenshitsya massiv v rezultate toj ili inoj operacii i kak v dalnejshem budet proishodit rabota s massivom on imeet vozmozhnost pryamo ukazat trebuemuyu konechnuyu yomkost v komande izmeneniya razmera izbezhav takim obrazom bolshogo kolichestva bessmyslennyh peremeshenij Drugie dinamicheskie algoritmy razmesheniya Sushestvuet mnozhestvo algoritmov realizacii dinamicheskih massivov krome vysheopisannogo Tak vozmozhna realizaciya s pomoshyu dinamicheskih yacheek pamyati svyazannyh ssylkami drugih razlichnyh struktur dannyh Bolshinstvo takih metodov obespechivayut preimushestvo v kakih to opredelyonnyh usloviyah no libo ne obespechivaet konstantnogo vremeni dostupa libo nesovmestimo so staticheskimi massivami i poetomu ne mozhet rabotat s nizkourovnevym kodom IspolzovanieDinamicheskie massivy ispolzuyutsya dlya obrabotki naborov odnorodnyh dannyh razmer kotoryh ne izvesten tochno na moment napisaniya programmy no kotorye potencialno mogut razmestitsya v dostupnoj pamyati Bez ispolzovaniya dinamicheskih massivov reshenie takih zadach svoditsya k odnoj iz strategij vydelenie staticheskogo massiva bolshogo razmera zavedomo dostatochnogo dlya polnogo razmesheniya dannyh ispolzovanie staticheskogo massiva v kachestve bufera v kotoryj dannye zagruzhayutsya chastyami primenenie inyh dinamicheskih struktur dannyh naprimer spiskov Pervyj variant primenim tolko kogda razmer nabora dannyh menyaetsya v nebolshom zhyostko ogranichennom diapazone naprimer v tekstovoj obrabotke ogranichenie v 1000 znakov na stroku vpolne priemlemo V protivnom sluchae vybor malenkogo massiva budet ogranichivat funkcionalnost programmy a bolshogo tak chtoby zavedomo hvatilo dlya lyubyh vhodnyh dannyh privedyot k neeffektivnomu rashodovaniyu pamyati Buferizaciya obrabotki uslozhnyaet algoritm a drugie dinamicheskie struktury v zadachah obrabotki bolshih posledovatelnostej prostyh dannyh po effektivnosti ne mogut sravnitsya s massivom Ispolzovanie dinamicheskih massivov pozvolyaet vydelit rovno stolko pamyati skolko realno neobhodimo srazu esli zadacha pozvolyaet opredelit obyom do zagruzki dannyh libo v processe zagruzki rasshiryaya massiv po mere neobhodimosti zagruzit vse dannye v odin massiv i edinoobrazno ih obrabotat Nedostatki odnako imeyutsya i u etoj strategii snizhenie skorosti raboty iz za nakladnyh rashodov na izmenenie razmera dinamicheskogo massiva potencialnoe snizhenie nadyozhnosti pri ekstremalno bolshom obyome vhodnyh dannyh popytka uvelichit massiv do sootvetstvuyushih razmerov mozhet privesti k vnezapnomu sushestvennomu zamedleniyu ili dazhe otkazu programmy iz za nedostatka svobodnoj pamyati V celom mozhno zametit chto podderzhka dinamicheskih massivov povyshaet udobstvo razrabotki no ne osvobozhdaet programmista ot neobhodimosti provodit ocenku potrebnostej programmy v pamyati takzhe ona trebuet ponimaniya osobennostej konkretnoj realizacii dinamicheskih massivov i soglasovaniya algoritmov obrabotki dannyh s etimi osobennostyami PrimeryPaskal Dinamicheskie massivy podderzhivayutsya Delphi FreePascal no ne Turbo Pascal var byteArray Array of Byte Odnomernyj massiv multiArray Array of Array of string Mnogomernyj massiv begin Ustanovit razmer odnomernogo massiva v n elementov SetLength byteArray n Dostup k dinamicheskomu massivu analogichen dostupu k obychnomu Indeksaciya vsegda nachinaetsya s nulya indeksy vsegda celye byteArray 0 10 Izmenit razmer do m elementov SetLength byteArray m Ustanovit razmer dvumernogo massiva v X Y elementov SetLength multiArray X Y multiArray 7 35 ru wikipedia org end Si V samom yazyke Si net dinamicheskih massivov no funkcii standartnoj biblioteki malloc free i realloc pozvolyayut realizovat massiv peremennogo razmera int mas int malloc sizeof int n Sozdanie massiva iz n elementov tipa int mas int realloc mas sizeof int m Izmenenie razmera massiva s n na m s sohraneniem soderzhimogo free mas Osvobozhdenie pamyati posle ispolzovaniya massiva Neudobstvo dannogo podhoda sostoit v neobhodimosti vychislyat razmery vydelyaemoj pamyati primenyat yavnoe preobrazovanie tipa i tshatelno otslezhivat vremya zhizni massiva kak i vsegda pri rabote s dinamicheski vydelennoj pamyatyu v Si Mnogomernyj dinamicheskij massiv mozhet byt sozdan kak massiv ukazatelej na massivy int A int malloc N sizeof int for int i 0 i lt N i A i int malloc M sizeof int Odnako rost razmernosti sushestvenno uslozhnyaet procedury sozdaniya massiva i osvobozhdeniya pamyati po zavershenii ego ispolzovaniya Eshyo bolee uslozhnyaetsya zadacha izmeneniya razmera massiva po odnoj ili neskolkim koordinatam Nekotorye kompilyatory Si predostavlyayut nestandartnuyu bibliotechnuyu funkciyu void alloca size t size neskolko uproshayushuyu rabotu s dinamicheskimi massivami Eta funkciya vydelyaet pamyat ne v kuche kak malloc a na steke i eta pamyat avtomaticheski osvobozhdaetsya pri dostizhenii operatora return To est pri vydelenii pamyati dinamicheskogo massiva etoj funkciej ego ne nuzhno udalyat vruchnuyu no takoj massiv nevozmozhno vernut iz funkcii v tochku vyzova Nachinaya s versii standarta C99 v yazyk vvedeny massivy peremennoj dliny V obychnom sintaksise opisaniya massiva Si na meste razmera massiva mozhet ukazyvatsya ne tolko konstanta no i peremennaya celogo tipa void func int arraySize int mas arraySize Opisanie massiva peremennoj dliny for int i 0 i lt arraySize i mas i anotherFunc i Obrashenie k elementam massiva Massiv peremennoj dliny mozhet poluchit lyuboj neobhodimyj razmer v moment sozdaniya Pamyat pod nego vydelyaetsya na steke Massiv peremennoj dliny sushestvuet do vyhoda iz oblasti vidimosti v kotoroj on byl obyavlen posle chego ego pamyat avtomaticheski osvobozhdaetsya Kak i v predydushem sluchae massiv peremennoj dliny nevozmozhno vernut iz funkcii v tochku vyzova C V standartnoj biblioteke predusmotren shablonnyj klass std vector realizuyushij funkcionalnost dinamicheskogo massiva Obyavlyaem massiv mas iznachalno soderzhashij chisla 1 5 std vector lt int gt mas 1 2 3 4 5 mas reserve 100 Zarezervirovat mesto dlya hraneniya ne menee 100 elementov ne izmenyaya fakticheskij razmer Soderzhimoe ostayotsya prezhnim mas resize 50 Zadat yavnyj razmer rovno 50 elementov Nedostayushie elementy poluchat znachenie po umolchaniyu lishnie elementy budut udaleny mas i i Prisvoit i mu elementu znachenie i mas push back 100 Dobavit element v konec massiva int x mas back Obrashenie k poslednemu elementu v dannom primere x 100 mas pop back Udalit poslednij element std cout lt lt mas size lt lt lt lt mas capacity lt lt n Vyvesti yomkost i fakticheskij razmer auto mas2 mas Peremennaya mas2 soderzhit polnuyu kopiyu mas std vector imeet mnozhestvo metodov i operatorov chast iz kotoryh pokazana vyshe na primere Oni pozvolyayut obrashatsya po indeksu izmenyat v lyubuyu storonu razmer massiva ispolzovat ego kak stek zapisyvat novoe znachenie v proizvolnuyu poziciyu massiva so sdvigom ostalnyh elementov i voobshe podderzhivat semantiku angl kopirovat obmenivat peremeshat peredavat v funkcii i vozvrashat poelementno sravnivat s drugim obektom togo zhe tipa Upravlyaemym yavlyaetsya ne tolko aktualnyj razmer no i yomkost chto pozvolyaet optimizirovat process vydeleniya pamyati std vector realizuet princip RAII vladeet svoimi podobektami vydelyaet i osvobozhdaet pamyat i pravilno vyzyvaet konstruktory destruktory Standart C trebuet ot realizacii obyazatelnogo vypolneniya uslovij vse elementy massiva dolzhny hranitsya podryad v poryadke uvelicheniya indeksa v celostnom bloke operativnoj pamyati dolzhno byt garantirovano konstantnoe vremya dostupa k proizvolnomu elementu Nizkourovnevaya rabota s dinamicheskoj pamyatyu mozhet realizovyvatsya sredstvami unasledovannymi ot yazyka predka no dlya obespecheniya tipobezopasnosti i soblyudeniya trebovanij obektnoj modeli pamyat pod massivy rekomenduetsya vydelyat posredstvom specifichnyh dlya yazyka operatorov new i delete Vydelenie pamyati pod massiv int dlinoj n int mas new int n Osvobozhdenie pamyati massiva delete mas Pomimo prochego eto pozvolyaet pereopredelyat operatory new i delete dlya polzovatelskih tipov i takim obrazom realizovyvat sobstvennye shemy raspredeleniya pamyati V sovremennom C ruchnoe upravlenie pamyatyu yavlyaetsya neotemlemym fundamentom dlya realizacii shablonnyh kontejnerov odnako predstavlyaet znachitelnye trudnosti dazhe dlya opytnyh programmistov i ne rekomenduetsya k ispolzovaniyu v prikladnom kode Primechaniyastd vector cppreference com neopr Data obrasheniya 16 oktyabrya 2021 Arhivirovano 28 iyunya 2011 goda C Core Guidelines R 1 Manage resources automatically using resource handles and RAII Resource Acquisition Is Initialization neopr Data obrasheniya 16 oktyabrya 2021 Arhivirovano 8 fevralya 2020 goda C Core Guidelines R 11 Avoid calling new and delete explicitly neopr Data obrasheniya 16 oktyabrya 2021 Arhivirovano 8 fevralya 2020 goda U etoj stati po informacionnym tehnologiyam est neskolko problem pomogite ih ispravit V state ne hvataet ssylok na istochniki sm rekomendacii po poisku Informaciya dolzhna byt proveryaema inache ona mozhet byt udalena Vy mozhete otredaktirovat statyu dobaviv ssylki na avtoritetnye istochniki v vide snosok 26 noyabrya 2013 Etu statyu neobhodimo ispravit v sootvetstvii s pravilami Vikipedii ob oformlenii statej Pozhalujsta pomogite uluchshit etu statyu 26 noyabrya 2013 Pozhalujsta posle ispravleniya problemy isklyuchite eyo iz spiska parametrov Posle ustraneniya vseh nedostatkov etot shablon mozhet byt udalyon lyubym uchastnikom
