Поскольку объем "кучи"
конечен, она может когда-нибудь исчерпаться. Если для удовлетворения очередного запроса на выделение памяти не существует достаточно свободной памяти, оператор new потерпит фиаско, и будет сгенерировано исключение. Исключение— это ошибка специального типа, которая возникает во время выполнения программы (в C++ предусмотрена целая подсистема, предназначенная для обработки таких ошибок). (Исключения описаны в главе 17.) В общем случае ваша программа должна обработать подобное исключение и по возможности выполнить действие, соответствующее конкретной ситуации. Если это исключение не будет обработано вашей программой, ее выполнение будет прекращено.Такое поведение оператора new
в случае невозможности удовлетворить запрос на выделение памяти определено стандартом C++. На такую реализацию настроены также все современные компиляторы, включая последние версии Visual C++ и C++ Builder. Однако дело в том, что некоторые более ранние компиляторы обрабатывают new-инструкции по-другому. Сразу после изобретения языка C++ оператор new при неудачном выполнении возвращал нулевой указатель. Позже его реализация была изменена так, чтобы в случае неудачи генерировалось исключение, как было описано выше. Поскольку в этой книге мы придерживаемся стандарта C++, то во всех представленных здесь примерах предполагается именно генерирование исключения. Если же вы используете более старый компилятор, обратитесь к прилагаемой к нему документации и уточните, как реализован оператор new (при необходимости внесите в примеры соответствующие изменения).Поскольку исключения рассматриваются ниже в этой книге (после темы классов и объектов), мы не будем пока отвлекаться на обработку исключений, генерируемых в случае неудачного выполнения оператора new
. Кроме того, ни один из примеров в этой и последующих главах не должен вызвать неудачного выполнения оператора new, поскольку в этих программах запрашивается лишь несколько байтов. Но если такая ситуация все же возникнет, то в худшем случае это приведет к завершению программы. В главе 17, посвященной обработке исключений, вы узнаете, как обработать исключение, сгенерированное оператором new.Рассмотрим пример программы, которая иллюстрирует использование операторов new
и delete.
#include
using namespace std;
int main()
{
int *p;
p = new int; // Выделяем память для int-значения.
*p = 20; // Помещаем в эту область памяти значение 20.
cout << *р; // Убеждаемся (путем вывода на экран) в работоспособности этого кода.
delete р; // Освобождаем память.
return 0;
}
Эта программа присваивает указателю р адрес (взятой из "кучи"
) области памяти, которая будет иметь размер, достаточный для хранения целочисленного значения. Затем в эту область памяти помещается число 20, после чего на экране отображается ее содержимое. Наконец, динамически выделенная память освобождается.Благодаря такому способу организации динамического выделения памяти оператор delete
необходимо использовать только с тем указателем на память, который был возвращен в результате new-запроса на выделение памяти. Использование оператора delete с другим типом адреса может вызвать серьезные проблемы.Инициализация динамически выделенной памяти
Используя оператор new
, динамически выделяемую память можно инициализировать. Для этого после имени типа задайте начальное значение, заключив его в круглые скобки. Например, в следующей программе область памяти, адресуемая указателем p, инициализируется значением 99.
#include
using namespace std;
int main()
{
int *p;
p = new int (99); // Инициализируем память числом 99.
cout << *p; // На экран выводится число 99.
delete p;
return 0;
}
Выделение памяти для массивов
С помощью оператора new
можно выделять память и для массивов. Вот как выглядит общий формат операции выделения памяти для одномерного массива:
переменная-указатель = new тип [размер];
Здесь элемент размер
задает количество элементов в массиве.Чтобы освободить память, выделенную для динамически созданного массива, используйте такой формат оператора delete
:
delete [] переменная-указатель;
Здесь элемент переменная-указатель
представляет собой адрес, полученный при выделении памяти для массива (с помощью оператора new). Квадратные скобки означают для C++, что динамически созданный массив удаляется, а вся область памяти, выделенная для него, автоматически освобождается.