С++ для начинающих




Динамическое создание и уничтожение массивов - часть 2


Оператор new допустимо использовать для задания первого измерения массива с помощью значения, вычисляемого во время выполнения. Предположим, у нас есть следующие C-строки:

const char *noerr = "success";

// ...

const char *err189 = "Error: a function declaration must "

                     "specify a function return type!";

Размер создаваемого с помощью оператора new массива может быть задан значением, вычисляемым во время выполнения:

#include <cstring>

const char *errorTxt;

if (errorFound)

    errorTxt = errl89;

else

    errorTxt = noerr;

int dimension = strlen( errorTxt ) + 1;

char *strl = new char[ dimension ];

// копируем текст ошибки в strl

strcpy( strl, errorTxt );

dimension разрешается заменить выражением:

// обычная для С++ идиома,

// иногда удивляющая начинающих программистов

char *strl = new char[ str1en( errorTxt ) + 1 ];

Единица, прибавляемая к значению, которое возвращает strlen(), необходима для учета завершающего нулевого символа в C-строке. Отсутствие этой единицы – весьма распространенная ошибка, которую достаточно трудно обнаружить, поскольку она проявляет себя косвенно: происходит затирание какой-либо другой области программы. Почему? Большинство функций, которые обрабатывают массивы, представляющие собой С-строки символов, пробегают по элементам, пока не встретят завершающий нуль.

Если в конце строки нуля нет, то возможно чтение или запись в случайную область памяти. Избежать подобных проблем позволяет класс string из стандартной библиотеки С++.

Отметим, что только первое измерение массива, создаваемого с помощью оператора new, может быть задано значением, вычисляемым во время выполнения. Остальные измерения должны задаваться константами, известными во время компиляции. Например:

int getDim();

// создание двумерного массива

int (*pia3)[ 1024 ] = new int[ getDim() ][ 1024 ]; // правильно

// ошибка: второе измерение задано не константой

int **pia4 = new int[ 4 ][ getDim() ];

Оператор delete для уничтожения массива имеет следующую форму:

delete[] str1;

Пустые квадратные скобки необходимы. Они говорят компилятору, что указатель адресует массив, а не единичный элемент. Поскольку тип str1 – указатель на char, без этих скобок компилятор не поймет, что удалять следует целый массив.

Отсутствие скобок не является синтаксической ошибкой, но правильность выполнения программы не гарантируется (это особенно справедливо для массивов, которые содержат объекты классов, имеющих деструкторы, как это будет показано в разделе 14.4).

Чтобы избежать проблем, связанных с управлением динамически выделяемой памятью для массивов, рекомендуется пользоваться контейнерными типами из стандартной библиотеки, такими, как vector, list или string. Они управляют памятью автоматически. (Тип string был представлен в разделе 3.4, тип vector – в разделе 3.10. Подробное описание контейнерных типов см. в главе 6.)




Содержание  Назад  Вперед