一尘不染

在C / C ++中处理内存不足情况的合适方法是什么?

linux

我正在编写一个消耗大量内存的缓存应用程序。

希望我会足够好地管理内存,但是我只是在考虑如果内存用完了该怎么办。

如果分配一个简单对象的调用失败,那么即使是syslog调用也可能失败吗?

编辑:好的,也许我应该澄清这个问题。如果malloc或new返回NULL或0L值,则从本质上讲这意味着调用失败,并且由于某种原因它无法为您提供内存。那么,在这种情况下明智的做法是什么?

EDIT2:我刚刚意识到对“
new”的调用会引发异常。这可能会在更高层次上被发现,所以我也许可以优雅地退出。此时,根据释放的内存量,甚至有可能恢复。到那时,我至少应该希望能够记录一些内容。因此,尽管我看到了在new之后检查指针值的代码,但这不是必需的。在C语言中,应检查malloc的返回值。


阅读 239

收藏
2020-06-03

共1个答案

一尘不染

好吧,如果您遇到分配内存失败的情况,那么您将获得一个std::bad_alloc例外。异常导致程序堆栈被取消缠绕。很有可能,应用程序逻辑的内部循环不会处理内存不足的情况,只有应用程序的更高级别可以这样做。由于堆栈即将解开,因此将释放大量内存-
实际上,它应该几乎是程序所使用的所有内存。

一个例外是当您请求无法满足的很大(例如几百MB)内存块时。但是,当发生这种情况时,通常会剩下足够小的内存块,这将使您能够优雅地处理故障。

堆栈展开是您的朋友;)

编辑: 刚意识到这个问题也用C标记了-如果是这种情况,那么当发现内存不足的情况时,您应该让您的函数手动释放其内部结构;不这样做是内存泄漏。

EDIT2: 示例:

#include <iostream>
#include <vector>

void DoStuff()
{
    std::vector<int> data;
    //insert a whole crapload of stuff into data here.
    //Assume std::vector::push_back does the actual throwing
    //i.e. data.resize(SOME_LARGE_VALUE_HERE);
}

int main()
{
    try
    {
        DoStuff();
        return 0;
    }
    catch (const std::bad_alloc& ex)
    {   //Observe that the local variable `data` no longer exists here.
        std::cerr << "Oops. Looks like you need to use a 64 bit system (or "
                     "get a bigger hard disk) for that calculation!";
        return -1;
    }
}

EDIT3:
好的,据评论员说,有一些系统在这方面没有遵循标准。另一方面,在这样的系统上,无论如何您都将成为SOL,所以我不明白为什么他们值得讨论。但是,如果您使用的
这样的平台,则应牢记这一点。

2020-06-03