C++中检查new是否成功分配内存

C++中检查new是否成功分配内存

在练习性质的代码中,我们都假定 new 将返回一个指向内存块的有效指针。事实上,除非请求分配的内存量特大,或系统处于临界状态,可供使用的内存很少,否则 new 一般都能成功。有些应用程序需要请求分配大块的内存(如数据库应用程序),因此最好不要假定内存分配能够成功。 C++提供了两种确认指针有效的方法,默认方法是使用异常(这也是前面一直使用的方法),即如果内存分配失败,将引发 std::bad_alloc 异常。这导致应用程序中断执行,除非您提供了异常处理程序,否则应用程序将崩溃,并显示一条类似于“异常未处理”的消息。
以下示例程序演示了如何使用异常处理检查分配请求是否失败:

#include 
using namespace std;

// remove the try-catch block to see this application crash 
int main()
{
    try
    {
        // Request a LOT of memory!
        int* pointsToManyNums = new int [0x1fffffff];

        // Use the allocated memory 

        delete[] pointsToManyNums;
    }
    catch (bad_alloc)
    {
        cout << "Memory allocation failed. Ending program" << endl;
    }
    return 0;
}

输出:

Memory allocation failed. Ending program

分析:
在您的计算机上,这个程序的执行情况可能不同。在我的计算机上,无法为 536870911 个整型分配内存,如果没有编写异常处理程序(第 14~17 行的 catch 块),程序将以令人非常讨厌的方式结束。
要查看这个程序在没有异常处理程序时的行为,可将第 6、 7 和 13~17 行注释掉。使用 Microsoft Visual Studio 以调试模式生成可执行文件,并在 Microsoft Visual Studio 外部执行它时,将出现Debug Error! 的输出。

由此可知,当内存分配导致程序无法正常执行时, try-catch 异常处理结构让程序能够向用户指出这一点,再正常退出。
不想依赖于异常的程序员可使用 new 变种 new(nothrow), 这个变种在内存分配失败时不引发异常,而返回 NULL,让您能够在使用指针前检查其有效性,如以下示例程序所示:

#include 
using namespace std;

int main()
{
    // Request LOTS of memory space, use nothrow 
    int* pointsToManyNums = new(nothrow) int [0x1fffffff];

    if (pointsToManyNums) // check pointsToManyNums != NULL
    {
        // Use the allocated memory 
        delete[] pointsToManyNums;
    }
    else 
        cout << "Memory allocation failed. Ending program" << endl;

    return 0;
}

输出:

Memory allocation failed. Ending program

分析:
这个程序与程序清单8.15相同, 但使用的是new(nothrow)。这个变种在分配内存失败时返回NULL,让我们能够在使用指针前检查其有效性,如第 8 行所示。这两种做法都可行,如何选择取决于您。

该文章会更新,欢迎大家批评指正。

推荐一个零声学院的C++服务器开发课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容
点击立即学习:C/C++后台高级服务器课程

你可能感兴趣的:(C++编程基础,c++)