Работа с векторами и матрицами (Лабораторная работа № 1), страница 4

Рассмотренные ранее массивы являются статическими; ячейки памяти для них выделяются на этапе компиляции и сохраняются в течение всего времени работы программы. В языке С++ также имеется и широко используется механизм динамического выделения памяти для данных, в том числе и массивов. При его использовании ячейки памяти выделяются или освобождаются во время работы программы. Это позволяет создавать массивы, когда в них возникает необходимость, и уничтожать их, когда они становятся ненужными, освобождая место в памяти для других объектов.

Динамическое распределение памяти осуществляется в С++ с помощью операций new и delete. Их использование иллюстрируется следующим листингом.

Листинг 4

// Динамическое выделение памяти под одномерный массив

#include <iostream.h>

#include <conio.h>

void main()

{

// описаниеданных

     int i,n;

     double *V=NULL;

// вывод указателя

     clrscr();

     cout<<"Исходное значение указателя"<<endl;

cout<<"V = "<<V<<endl;

     getch();

// ввод числа элементов массива

     cout<<endl<<"Введите n  ";  cin>>n;

// выделение памяти

     V= new double[n+1];

     if (V==NULL)

       {

       cout<<"Недостаточно памяти!"<<endl;

       getch();

       return;

       }

// вывод указателя

     cout<<endl<<"Значение указателя после выделения памяти"<<endl;

cout<<"V = "<<V<<endl;

     getch();

// заполнениемассива

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

       V[i]=i;

// вывод массива на дисплей

     cout<<endl;

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

       cout<<i<<"  "<<V[i]<<endl;

getch();

// освобождение памяти

     delete [] V;

// вывод указателя

     cout<<endl<<"Значение указателя после очистки памяти"<<endl;

cout<<"V = "<<V<<endl;

     getch();

// обнуление указателя

     V=NULL;

// вывод указателя

     cout<<endl<<"Значение указателя после его обнуления"<<endl;

cout<<"V = "<<V<<endl;

     getch();

}

Сначала объявляется указатель V (идентификатор будущего массива) на переменную типа double (тип элементов будущего массива). Одновременно он инициализируется константой NULL. После определения размера массива (переменная n), выполняется операция выделения памяти:

V = new double[n];

Если памяти для заданного размера недостаточно, то указатель сохранит или получит значение NULL и произойдет вывод соответствующего сообщения и завершение работы программы. Если же ресурсов памяти достаточно, то произойдет выделение необходимого количества ячеек и указателю V будет присвоено значение адреса нулевого элемента массива. Далее с массивом можно работать как обычно. Необходимо только помнить, что n – число элементов массива при начале их нумерации с нуля и можно работать с индексами от 0 до n-1. В данном примере массив заполняется значениями, равными порядковым номерам элементов, а затем эти значения выводятся на дисплей. Нулевой элемент массива не используется.

Освобождение памяти выполняется командой

delete [] V;

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

В приведенном примере значение указателя на массив (адрес нулевой ячейки) несколько раз выводится на дисплей, чтобы продемонстрировать, что с ним происходит.

Динамическое выделение памяти под двумерный массив осуществляется несколько сложнее. Возможны два варианта: с заранее известным числом столбцов или с определяемым в процессе работы программы. Первый вариант представлен на листинге 5.

Листинг 5

// Динамическое выделение памяти под двумерный массив

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

void main()

{

// описание данных

     int i,j,m;

     double (*A)[10]=NULL;

// вывод указателя

     clrscr();

     cout<<"Исходное значение указателя"<<endl;

cout<<"A = "<<A<<endl;

     getch();

// ввод числа строк

     cout<<endl<<"Введите число строк  ";  cin>>m;