当操作系统无法分配内存时,使用 STL 的应用程序是否应该容易出现内存泄漏?

2024-01-04

我个人不喜欢异常处理。正如许多地方建议的那样不建议将捕获异常并继续执行程序作为良好的编程实践。

然而,自从STL容器抛出异常(即 bad_alloc),除了在我们的代码中使用异常处理块之外别无选择。但是,在处理应用程序中的 STL 调用时,我发现要使应用程序防漏且健壮非常困难。

下面的示例代码演示了 STL(带有异常处理)如何可能导致内存泄漏:

void my_function()
{
    try
    {
        std::vector<int> integers; // It can throw bad_alloc here (1)

        for (int i=0; i<10240; i++)
        {
            int* myintptr = new (std::nothrow) int;
            if (myintptr == NULL) // Memory not allocated. But no exception thrown so I am safe to continue.
                continue;
            *myintptr = i;
            integers.push_back (*myintptr ); // It can throw bad_alloc here (2)
            delete myintptr;
        }
    }
    catch(std::bad_alloc& ba)
    {
        // If it come here after throwing exception at (1) its fine. But if it has thrown exception at (2) then it just leaked memory allocated by new int
    }
}

(当然,这只是简化版本,用于演示大型复杂代码中的类似情况。)

现在,这里可能有一些建议:

1. 在最狭窄的块上使用异常处理:所以这意味着我必须在调用push_back 周围放置另一个try..catch。但是,如果我想在每个 STL 调用周围放置 try...catch 块,我的代码会是什么样子?

2.确保有足够的内存:也可能建议我们不应该陷入操作系统无法分配内存的情况。因此,我们可以在继续 STL 调用之前主动检查是否有足够的可用内存。 但这种策略并不总是有效。拥有足够的可用内存并不能保证我们进一步的内存分配请求会成功(例如,如果内存碎片。 此外,如果系统上正在运行其他大量消耗内存的应用程序,那么操作系统可能会发现很难在物理内存中找到空间进行分配,因此它可能会拒绝该请求。)

所以最后最大的问题是:

我们怎样才能使使用STL的应用程序健壮(不崩溃,即使操作系统拒绝内存分配请求也能继续运行)和充分证明(即使有异常也不会泄漏)?


你应该了解RAII http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization!基本思想是,任何资源都不会受到在销毁时清理资源的对象的保护。由于每当剩下一个块时都会调用局部变量的析构函数(除非使用类似longjmp())这种方法完全自动化清理。 RAII 技术部分是为了处理异常而开发的,但即使没有抛出任何异常,我发现这种编程风格也可以显着减少资源泄漏。

顺便说一句,您强调的关于出现异常时不继续的建议绝对是无稽之谈!此外,除了少数可以合理重新启动操作的位置之外,您可能不会有任何try/catch块!它们对于处理资源清理当然没有什么用处,并且主要用于处理实际问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当操作系统无法分配内存时,使用 STL 的应用程序是否应该容易出现内存泄漏? 的相关文章

随机推荐