【问题标题】:c++ allocator crashes the application when not enough memory [duplicate]当内存不足时,c ++分配器使应用程序崩溃[重复]
【发布时间】:2019-01-07 19:55:56
【问题描述】:

当分配器由于内存有限而失败时。该应用程序正在崩溃。抛出 bad_alloc 或返回 nullptr 不会停止崩溃。有人知道吗?

pointer allocator<T>(size_type count) const
{
    void* buffer = new (count * sizeof(T));
    if (!buffer)         // if buffer == nullptr crashes app
        throw bad_alloc; // doing this crashes app
    /* or alternatively
     * try {
     *     void* buffer = new (count * sizeof(T));
     * } catch (const std::exception& e) {
     *     std::cerr << "failed to allocate " << count << std::endl;
     *     return nullptr;
     * }
     */
}

那么如何优雅地关闭应用并说内存不足?

【问题讨论】:

  • 什么样的崩溃?什么是回溯?
  • @n.m.目前还不清楚这里要问什么,但我怀疑这个问题是重复的。
  • 这里是示例jrruethe.github.io/blog/2015/11/22/allocators。尝试在分配器中将 UINT64_MAX 分配为 count 看看会发生什么

标签: c++ c++11 stl


【解决方案1】:

为了不传播异常,需要做很多事情,标准通过指定如果异常会逃逸,则调用std::terminate 来做到这一点。

如果没有您程序其余部分的上下文,我们无法知道它是否是其中之一,或者只是留下main 的异常。

对后者的修复可能看起来像

int main()
{
    try 
    {
        // whatever here
    }
    catch (std::exception & e)
    {
        std::cerr << e.what();
        return EXIT_FAILURE;
    }
}

【讨论】:

  • 在 main 有一个异常捕获。所以事实并非如此。
【解决方案2】:

new 运算符会自行抛出 bad_alloc!所以使用try-catch 块:

pointer allocator<T>(size_type count) const
{
    try
    {
        void* buffer = new (count * sizeof(T));
    }
    catch (bad_alloc& ba)
    {
        return nullptr; // or do whatever you have to do to recover
    }
}

另一个例子见here

【讨论】:

  • 好吧,即使我这样做,如前所述“返回 nullptr”也会导致 STL 崩溃。我希望 STL 优雅地返回异常“bad_alloc”。但它只是简单地使应用程序崩溃。
  • 捕获 bad_alloc 不是问题。从中恢复是个问题。因为调用来自 STL,并且 return nullptr crash with in STL
  • 而不是捕获异常,call the std::nothrow overload of operator new
  • @AdnanShaheen 从内存不足错误中恢复的唯一方法是以某种方式释放内存,然后重新运行分配请求。没有别的办法。
猜你喜欢
  • 2012-07-01
  • 1970-01-01
  • 2019-06-19
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
相关资源
最近更新 更多