Назад к вопросам
Middle
82
questionbank

Что происходит, если оператор new не может выделить память?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Вызывается обработчик исключения std::bad_alloc. По умолчанию этот обработчик завершает программу вызовом std::terminate.

Можно установить свой обработчик с помощью std::set_new_handler. Он будет вызываться, если выделение памяти не удалось. Обработчик должен либо освободить память для последующей попытки new, либо бросить исключение, либо завершить программу (abort, exit).

Существует также не выбрасывающая исключения версия оператора new (new (std::nothrow)), которая в случае неудачи возвращает nullptr.

#include <iostream>
#include <new>
#include <cstdlib>

// Пользовательский обработчик
void my_new_handler() {
    std::cerr << "Ошибка выделения памяти!" << std::endl;
    // Попытка освободить память или завершить программу
    std::abort();
}

int main() {
    try {
        // Установка пользовательского обработчика
        std::set_new_handler(my_new_handler);

        // Попытка выделить большой объем памяти
        int* large_array = new int[1000000000000000000ULL]; // Очень большой размер
        
        // Этот код не будет достигнут в случае успешного вызова обработчика
        delete[] large_array;

    } catch (const std::bad_alloc& e) {
        // Этот блок кода будет выполнен, если my_new_handler
        // выбросит исключение std::bad_alloc (что не соответствует
        // поведению my_new_handler выше)
        std::cerr << "Исключение: " << e.what() << std::endl;
    }

    // Не выбрасывающая версия new
    int* array_nothrow = new (std::nothrow) int[1000000000000000000ULL];
    if (array_nothrow == nullptr) {
        std::cerr << "Не удалось выделить память с помощью new (std::nothrow)" << std::endl;
    } else {
        delete[] array_nothrow;
    }

    return 0;
}