操作系统无法分配内存时,使用STL的应用程序应该是内存泄漏吗?

Atu*_*tul 2 c++ memory memory-management stl

我个人不是异常处理的粉丝.与许多地方一样,建议不要将捕获异常并继续执行程序作为良好的编程习惯.

但是,由于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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

现在,这里可能有几个建议:

1.在大多数缩小的块上使用异常处理:所以这意味着我要在call_back上调用另一个try..catch.但是,如果我想在每个STL调用周围放置try ... catch块,我的代码将如何显示?

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

所以最后一个大问题是:

我们如何使用STL强大的应用程序(没有崩溃,即使在操作系统拒绝内存分配请求时仍然运行)和完整的证据(即使有例外也没有泄漏)?

Die*_*ühl 7

你应该了解RAII!基本的想法是,你永远不会有任何资源没有被一个对象在被破坏时清理资源所守护.由于只要有一个块就会调用局部变量的析构函数(除非使用类似的东西longjmp()),这种方法完全自动化清理.RAII技术部分开发用于处理异常,但即使没有抛出,我发现这种编程风格可以显着减少资源泄漏.

顺便说一句,你强调的有关在异常时没有继续的建议绝对是胡说八道!此外,除了可以合理地重新启动操作的几个位置之外,您可能不会有任何try/ catch块!它们对于处理资源清理肯定没用,主要用于处理实际问题.