Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
217942_748E9_otvety_k_ekzamenu_po_programmirova...doc
Скачиваний:
7
Добавлен:
26.09.2019
Размер:
627.2 Кб
Скачать

1. Выделение памяти в соответствие с типом указателя

Оператор new состоит их ключевого слова new, за которым следует спецификатор типа. Оператор new возвращает не сам объект, а указатель на него.

Например: new int; выделяет в куче место под один объект типа int.

Особенностью памяти типа в куче является то, что размещаемые в ней объекты не имеют имени. Поэтому необходимо адрес этого объекта хранить в статистической переменной. Это легко сделать, т.к. оператор new возвращает вдрес вновь размещенного объекта.

int *p = new int; /*оператор new создает один объект типа int, на который ссылается указатель p. */

При выделении опрератор new не инициализирует память. Следовательно, объекты, создаваемые с помощью оператора new, рекомендуется инициализировать:

int *p = new int( 0 ); /*Константа в скобках задает начальное значение для создаваемого объекта; */

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

Оператор new выполняет следующую последовательность действий:

  • выделяет память

  • инициализирует его значением, стоящим в скобках

Для выделения памяти вызывается библиотечная функция new().

Если функция new() не может выделить затребованного количества памяти, она возбуждает исключение bad_alloc.

Время жизни объекта заканчивается при освобождении памяти. Память освобождается с помощью оператора delete.

Например: delete p;

оператор вызывает библиотечную функцию delete(), которая возвращает выделенную память в кучу(heap). Поскольку хип конечен, очень важно возвращать ее своевременно. Язык С++ гарантирует, что оператор delete не будет вызывать функцию delete() в случае нулевого операнда.

Объект в куче является динамическим и его время жизни завист от программиста. Когда в программе встречается оператор delete, p не обнуляется, а становится «висячим» указателем, т.е. ссылается на участок памяти, не занятый никакими объектами. Это может привести к трудно обнаруживаемым ошибкам, поэтому иногда рекомендуют после выполнения delete обнулять указатель:

delete p; p=0;

(Сам объект p является статическим. Адресуемый указателем p объект, который создается с помощью оператора new во время выполнения, является динамически размещенным объектом типа int. Память, отведенная самому указателю pi, не освобождается, а ее содержимое не изменяется.)

опасные и безопасные операторы delete:

void f() { int i; char str[11] = "dwarves"; int *p = &i; short *ps = 0; double *pd = new doub1e(33);

delete str; // плохо: str не является динамическим объектом

delete p; // плохо: pi ссылается на локальный объект

delete ps; // безопасно

delete pd; // безопасно }

3 Основные ошибки, связанные с динамическим выделением памяти:

• не освободить выделенную память. В таком случае память не возвращается в хип. Эта ошибка получила название утечки памяти;

• дважды применить оператор delete к одной и той же области памяти.

• изменять объект после его удаления. Такое часто случается, поскольку указатель, к которому применяется оператор delete, не обнуляется.