Краткие теоретические сведения
динамические массивы

 

При традиционном определении массива:
тип имя_массива [количество_элементов];
общее количество памяти, выделяемой под массив, задается определением и равно количество_элементов *
sizeof(тип).

 

Но иногда бывает нужно чтобы память под массив выделялась для решения конкретной задачи, причем ее размеры заранее не известны и не могут быть фиксированы.

 

            Формирование массивов с переменными размерами можно организовать с помощью указателей и средств динамического распределения памяти двумя способами:

 

1)     с использованием библиотечных функций, описанных в заголовочных файлах alloc.h и stdlib.h (стандартный Си);

 

2)     с использованием операций new и delete (Си++).

 

 

1.1.     Формирование динамических массивов с использованием библиотечных функций

 

Для выделения и освобождения динамической памяти используются функции

Функция

Прототип и краткое описание

malloc

void * malloc(unsigned s)

Возвращает указатель на начало области динамической памяти длиной в s байт, при неудачном завершении возвращает NULL

calloc

void * calloc(unsigned n, unsigned m)

Возвращает указатель на начало области динамической памяти для размещения n элементов длиной по m байт каждый, при неудачном завершении возвращает NULL

realloc

void * realloc(void * p, unsigned s)

Изменяет размер блока ранее выделенной динамической памяти до размера s байт, р- адрес начала изменяемого блока, при неудачном завершении возвращает NULL

free

void *free(void p)

Освобождает ранее выделенный участок динамической памяти, р – адрес первого байта

 

Пример:

Функция для формирования одномерного динамического массива

int * make_mas(int n)

(

int *mas;

mas=(int*)malloc(n*sizeof(int));

for(int i=0;i<n;i++)

mas[i]=random(10);

return mas;

}

 

Для выделения памяти используется функция malloc, параметром которой является размер выделяемого участка памяти равный n*sizeof(int). Так как функция malloc возвращает нетипизированный указатель void*, то необходимо выполнить преобразование полученного нетипизированного указателя в указатель int*.

Освободить выделенную память можно функцией free(mas).

 

 

1.2.     Формирование динамических массивов с использованием операций new и delete

 

Для динамического распределения памяти используются операции new и delete.

Операция

new имя_типа

или

new имя_типа инициализатор

 

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

 

Примеры:

1) int *i;

   i=new int(10);

 

2) float *f;

   f=new float;

 

3)     int *mas=new[5];

 

В примерах 1, 2 показано как выделить память под скалярные переменные, пример 3 показывает выделение памяти под массив переменных.

 

     Операция delete указатель освобождает участок памяти ранее выделенный операцией new.

Пример:

 

 

 

Функция для формирования двумерного динамического массива

int ** make_matr(int n)

{

int **matr;

int i,j;

matr=new int*[n];

for (i=0;i<n;i++)

  {

     matr[i]=new int[n];

     for (j=0;j<n;j++)

     matr[i][j]=random(10);

   };

return matr;

}

При формировании матрицы сначала выделяется памяти для массива указателей на одномерные массивы, а затем в цикле с параметром выделяется память под n одномерных массивов.

 

 

 

 

 

**matr

 

*matr[1]

*matr[2]

*matr[3]

. . . .

*matr[n]

 

 

 

 

 

 

 

 

 

 

 

 

Чтобы освободить память необходимо выполнить цикл для освобождения одномерных массивов

 

for(int i=0;i<n;i++)

delete matr[i];

 

После этого освобождаем память на которую указывает указатель matr

delete [] matr;