【问题标题】:std::unique_ptr dereference exception not catch-ed in try-catch blockstd::unique_ptr 取消引用异常未在 try-catch 块中捕获
【发布时间】:2018-05-22 09:49:50
【问题描述】:

假设我有:

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 取消引用异常?

编辑:我应该补充一点,这是在运行 MSVS2012 可执行文件的 Windows 7 机器上 - 如果它是相关的!

【问题讨论】:

  • 取消引用未初始化的指针是未定义的行为,不会引发异常。
  • @RichardCritten 哦....有没有办法做我想做的事? - 我有一个 unique_ptr 的列表 - 我试图通过在它周围放置一个 try 块来避免单独检查每个...但是如果它没有引发异常,那么我想我必须在每个周围做if (ptr) {...}
  • 为什么你拥有不拥有任何东西的智能指针 (std::unique_ptr)?这感觉像是一个 XY 问题。
  • @RichardCritten 我正在使用智能指针,这样我就不必担心垃圾收集等等......在我的代码中,当我创建一个新指针时,构造函数(类型为指向 ) 可能会失败,如果是这样,智能指针实际上是 nullptr。所以我想测试一下这个条件......
  • 当正在构造的对象失败并且不创建std::unique_ptr`时抛出异常。

标签: c++ c++11 exception-handling unique-ptr


【解决方案1】:

那么是否有可能捕获 unique_ptr 取消引用异常?

没有要捕获的unique_ptr 取消引用异常。

作为documentation says

如果get() == nullptr,则行为未定义

您可以使用这种类似 Java 的行为轻松编写自己的智能指针,但这确实意味着在 每个 取消引用时都要为测试和分支付费,这通常看起来很愚蠢。

对于cmets中描述的略有不同的问题:

我有一个 unique_ptr 的列表 - 我试图通过在其周围放置一个 try 块来避免单独检查每个。

理智的解决方案可能是检查一次,而不是每次取消引用:

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

对于后续的 cmets,您可以在构造函数中添加一个 check-and-throw 包装器。

在 C++17 中,您几乎可以通过返回 optional&lt;unique_ptr&lt;test&gt;&gt;(即,它包含填充的 unique_ptr,或根本不包含任何内容:在这种情况下,调用 value 来提取unique_ptr 会抛出 std::bad_optional_access 如果那里真的没有)。

如果你可以导入 ot(或者没有 C++17),GSL 可能会更好用gsl::not_null&lt;T&gt;。例如,您可以将这些东西存储在您的容器中

using unique_not_null = std::unique_ptr<gsl::not_null<test>>;

【讨论】:

  • “你可以在你的构造函数中添加一个检查并抛出包装器” - 比如gsl::not_null?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 2020-02-28
  • 1970-01-01
相关资源
最近更新 更多