Все разделы
Выбрать школу

Школа. Увлечения. Большое будущее.

PROSCHOOLS · ОБРАЗОВАНИЕ РЯДОМ

Ваш город

Выберите город, чтобы находить образование и возможности рядом.

Как учитываем городКаталог и кнопки «Выбрать школу» покажут школы выбранного города.Онлайн-курсы, учебник, ГДЗ и задания к экзаменам доступны по всей России.

Популярные города

Будет выбран: Вся Россия

Учебные материалы останутся прежними.

Поиск по сайту

По всему сайтуШколы выбранного города — выше в результатах

С чего начнём?

↑ ↓ — выбрать результат · Enter — открыть · Esc — закрыть

new и delete в C++: время жизни объектов и владение памятью

💻 Информатика · 10 класс

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

Клавиатура в компьютерном классе
Иллюстрация к предмету «Информатика»Hmartil · Wikimedia Commons · CC BY-SA 4.0

Что создаёт new

Выражение new создаёт объект с динамическим временем жизни и возвращает указатель на него. В простом случае int* value = new int(7); выделяется место и инициализируется число 7. Сам указатель value и объект, на который он указывает, — не одно и то же: у них могут быть разные времена жизни.

Обычный new при невозможности выделения памяти обычно сообщает об этом исключением std::bad_alloc. Нельзя описывать его как универсальный вызов, который всегда возвращает nullptr при неудаче: для варианта nothrow есть отдельные правила.

Парные операции

СозданиеОсвобождение
new T(...)delete pointer
new T[n]delete[] pointer

Delete завершает жизнь соответствующего объекта и освобождает связанное хранилище в обычном сценарии. Для массива нужна форма со скобками, даже если его элементы простые int. Неправильная пара операций ведёт к неопределённому поведению, а не к гарантированному понятному сообщению об ошибке.

Разобранный пример

#include <iostream>

int main()
{
    int* values = new int[3]{2, 4, 6};
    std::cout << values[1] << '\n';
    delete[] values;
    values = nullptr;
    return 0;
}

Вывод — 4, потому что индексация начинается с нуля. После delete[] обращаться к бывшим элементам нельзя. Присваивание nullptr меняет значение переменной-указателя, но не возвращает уничтоженный массив и не обнуляет другие указатели, которые могли указывать туда же.

Три типичные ошибки владения

  • Утечка: последняя ссылка потеряна, а объект не освобождён.
  • Повторное освобождение: один объект пытаются удалить дважды.
  • Использование после удаления: указатель сохранил адрес, но время жизни объекта закончилось.

Окончание функции само по себе не удаляет объект, созданный обычным new, только потому, что локальный сырой указатель вышел из области видимости. Именно поэтому нужно понимать, кто владеет ресурсом.

Почему чаще выбирают RAII

В современном прикладном C++ контейнер std::vector и умные указатели помогают связывать освобождение ресурса со временем жизни владельца. Для учебного массива часто достаточно std::vector<int> values{2, 4, 6};: отдельный delete в пользовательском коде не нужен. Изучение new/delete объясняет механизм, но не требует использовать их в каждой задаче.

Задания

  1. Чем освобождается new double[5]?
  2. Удаляет ли p = nullptr объект, ранее созданный через new?
  3. Если q скопирован из p, а затем объект удалён через p, становится ли q безопасным автоматически?

Ответы

1. delete[] p для соответствующего указателя. 2. Нет: присваивание лишь меняет указатель и может привести к утечке, если владелец потерян. 3. Нет: q остаётся висячим указателем; обнуление p не изменяет q.

Самопроверка

Для каждого динамического объекта назовите владельца, момент создания и завершение времени жизни. Если ответ расплывчатый, безопаснее сначала упростить структуру владения, чем добавлять случайные delete в разных ветвях.

Связанные материалы

Источники и материалы