Исключение разыменования std :: unique_ptr не перехвачено в блоке try-catch

Итак, допустим, у меня есть:

struct test {
    bool a;
    int b;
};

int main()
{
    std::unique_ptr<test> ptr;
    // don't init the ptr

    try
    {
        if (!ptr->a)
        {
            std::cout << "ok" << std::endl;
        }
    }
    catch (const std::exception &ex)
    {
        std::cout << "ex: " << ex.what() << std::endl;
    }

    return 1;
}

Итак, здесь я устанавливаю уникальный указатель, но я не инициализирую его (чтобы имитировать это в более крупной базе кода), но я хочу поймать исключение.

Проблема в том, что мое исключение не вызывается - просто вылетает (ошибка доступа к памяти)

Я прочитал несколько похожих вопросов (но не совсем одинаковых), в которых предлагалось передать исключение по ссылке, но это не сработало.

Так можно ли перехватить исключение отмены ссылки unique_ptr?

Обновлено: Я должен добавить, что это находится в окне Windows 7 с исполняемым файлом MSVS2012 - на случай, если это актуально!

Отмена ссылки на неинициализированный указатель является неопределенным поведением и не вызывает исключения.

Richard Critten 22.05.2018 11:54

@RichardCritten о ... есть ли способ сделать то, что я пытаюсь сделать? - У меня есть список unique_ptr - я пытался избежать индивидуальной проверки каждого из них, помещая вокруг него блок try ... но если он не генерирует исключение, тогда, я думаю, мне нужно выполнить if (ptr) {...} для каждого из них?

code_fodder 22.05.2018 11:56

Почему у вас есть умные указатели (std::unique_ptr), которым ничего не принадлежит? Это похоже на XY-проблему.

Richard Critten 22.05.2018 11:57

@RichardCritten Я использую умные указатели, чтобы мне не приходилось так сильно беспокоиться о сборке мусора и так далее ... В моем коде, когда я создаю новый указатель, конструктор (указанного типа) может выйти из строя, и если да умный указатель фактически равен nullptr. Итак, я хочу проверить это условие ....

code_fodder 22.05.2018 12:00

Выбрасывать исключение, когда конструируемый объект терпит неудачу, и не создавать std :: unique_ptr`.

Richard Critten 22.05.2018 12:07

@RichardCritten хорошо, поэтому я вызываю стороннюю функцию, которая возвращает либо указатель, либо nullptr. Я мог бы использовать необработанные указатели, но я хотел использовать unique_ptr для автоматической сборки мусора ... Я считаю, что это один из вариантов использования unique_ptr? Итак, исключение, которое я хочу вызвать, - это когда я получаю возвращенный nullptr ... В любом случае, я думаю, что вопрос получен (т.е. не могу делать то, что пытаюсь), я переместу проверку исключения, чтобы проверить каждый указатель. Не стесняйтесь добавлять свой первый комментарий в качестве ответа, я размечу его.

code_fodder 22.05.2018 12:11

Вы можете создать свой собственный умный указатель, который будет проверять / бросать каждый раз, когда вы его используете. Но это неизбежно несколько снижает производительность. Между прочим, C++ выдаст исключение (по умолчанию), если не сможет выделить ваш объект при его создании.

Galik 22.05.2018 12:34

Или заверните функцию стороннего создателя в чек.

Galik 22.05.2018 12:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
297
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

So is it possible to catch a unique_ptr de-reference exception?

Не существует исключения разыменования unique_ptr, которое можно было бы перехватить.

Как сообщает документация говорит,

The behavior is undefined if get() == nullptr

Вы можете легко написать свой собственный умный указатель с этим Java-подобным поведением, но это означает оплату теста и ветвления при разыменовании каждый, что в целом кажется глупым.

Для немного другой проблемы, описанной в комментариях:

I have a list of unique_ptr's - I was trying to avoid individually checking each one by putting a try block around it.

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

if (any_of(begin(ptrs), end(ptrs), logical_not<unique_ptr<test>>{})
{
  throw MyNullPointerException();
}

В последующих комментариях вы можете просто добавить обертку проверки и выброса к своей функции построения.

В C++ 17 вы можете почти получить то, что хотите, вместо этого вернув optional<unique_ptr<test>> (то есть он либо содержит заполненный unique_ptr, либо вообще ничего: в этом случае вызов value для извлечения unique_ptr приведет к выдаче std::bad_optional_access, если его нет. действительно один там).

Если вы можете импортировать ot (или у вас нет C++ 17), GSL, вероятно, будет даже лучше с gsl::not_null<T>. Например, вы можете вместо этого хранить эти вещи в своем контейнере.

using unique_not_null = std::unique_ptr<gsl::not_null<test>>;
"вы могли бы просто добавить обертку проверки и выброса к вашей функции построения" - Нравится gsl::not_null?
StoryTeller - Unslander Monica 22.05.2018 12:45

Другие вопросы по теме