Информатика и технология программирования

       

Динамические массивы и проблемы размерности данных


Как известно, любого ресурса всегда не хватает. В компьютерах это прежде всего относится к памяти. Если на проблему ее распределения посмотреть с обычных житейских позиций, то можно извлечь много полезного для понимания принципов статического и динамического распределения памяти.

Пусть наша программа обрабатывает данные от нескольких источников, причем заранее неизвестно, сколько . Как можно поступить в таком случае :



-самый неэффективный вариант : под каждый вид данных зарезервировать память заранее " по максимуму" . Применительно к массиву это означает, что мы заранее выбираем такую размерность, которая никогда не будет превышена. Но тем не менее, такое " никогда" рано или поздно может случиться , поэтому процесс заполнения массива лучше контролировать ;



-приемлемый вариант может быть реализован, если в какой-то момент времени выполнения программа " узнает" , какова в этот раз будет размерность обрабатываемых данных. Тогда она может создать динамический массив такой размерности и работать с ним. К сожалению, такое " знание" не всегда возможно ;



-идеальный вариант заключается в создании такой структуры данных, которая автоматически увеличивает свою размерность при ее заполнении. К сожалению, ни язык, ни библиотека здесь не помогут - такой массив можно реализовать только программно, по справедливости назвав ВИРТУАЛЬНЫМ МАССИВОМ.


//------------------------------------------------------bk47-03.cpp


// функция возвращает указатель на создаваемый


// динамический массив. Размерность массива увеличивается


// при заполнении с кратностью N - N, 2N, 3N ...


&#35define N 10
int *GetArray()
{
int i , *p; // Указатель на массив


p = new int[N]; // Массив начальной размерности


for (i=0; 1; i++)
{
cout &#60&#60 i &#60&#60 "-ый элемент";
cin &#62&#62 p[i];
if ((i+1)%N==0) // Массив заполнен ???


{ // Создать новый и переписать


int *q=new int[i+1+N];
for (int j=0; j&#60=i; j++)
q[j]=p[j];
delete p; p=q; // Считать новый за старый ,


} // а старый уничтожить


if (p[i]==0) return p; // Ограничитель ввода - 0


}
}

Более изящно это перераспределение можно сделать с помощью функции низкого уровня realloc , которая резервирует память новой размерности и переписывает в нее содержимое старой области памяти (либо расширяет существующую) :


p = (int*) realloc(p,sizeof(int)*(i+1+N));



Содержание раздела