set_new_handler函数及nothrow常量
一.C++11下的set_new_handler函数原型
new_handler set_new_handler
(new_handler new_p) noexcept;
其中,new_handler是一个函数指针,其定义如下 :typedef void (*new_handler)()。所以new_p为形参和返回值均为void
的函数名
二.set_new_handler使用方法
1.一个简单的使用案例
如下:
#include <iostream>
#include <new>
using namespace std;
void newErr(void)
{
cout << "new error" << endl;
system("pause");
exit(-1);
}
int main()
{
double * ptr[50];
set_new_handler(newErr);
for (int i = 0; i<50; i++)
{
ptr[i] = new double[50000000]; //不断申请空间
cout << "ptr[" << i << "]" << "->success" << endl;
}
system("pause");
return 0;
}
使用方法如下:
- 先定义一个
无参无返回
的函数,如void newErr(void) 在申请空间之前,即new之前
,调用set_new_hander()函数,并将1中定义的函数名当作参数传入,如set_new_handler(newErr);
这样,当申请空间出错时,会调用newErr()函数来处理错误。
2.注意事项
- 我们自己写的处理函数,如newErr(),最终一定是
抛出bad_alloc()异常
或终止程序
。不然的话,每当程序申请内存失败就会调用我们的处理函数,从而陷入死循环中。 - 一般来说,我们自己写的处理函数,如newErr(),
总是先释放某些内存空间,从而为new的内存申请提供更多的可用空间
,然后退出函数。 - 可以卸载当前的处理函数。具体方法是set_new_handler(nullptr),这样做之后,若是new失败,将不会调用处理函数,如不会调用newErr(),而是抛出异常。
下面再给出一个示例,参考至:[https://blog.csdn.net/kzq_qmi/article/details/45440505]
#include <iostream>
#include <new>
using namespace std;
/// buffer to be allocated after custom new handler has been installed
char* g_pSafetyBuffer = NULL;
/// exceptional one time release of a global reserve
void my_new_handler()
{
if (g_pSafetyBuffer) {
delete[] g_pSafetyBuffer;
g_pSafetyBuffer = NULL;
std::cout << "[Free some pre-allocated memory]";
return;
}
std::cout << "[No memory to free, throw bad_alloc]";
throw std::bad_alloc();
}
/// illustrates how a custom new handler may work
int main()
{
enum { MEM_CHUNK_SIZE = 1000 * 1000 }; // adjust according to your system
std::set_new_handler(my_new_handler);
g_pSafetyBuffer = new char[801 * MEM_CHUNK_SIZE];
try {
while (true) {
std::cout << "Trying another new... ";
new char[200 * MEM_CHUNK_SIZE];
std::cout << " ...succeeded.\n";
}
}
catch (const std::bad_alloc& e) {
std::cout << " ...failed.\n";
}
system("pause");
return 0;
}
打印结果如下:
上述例子用到了try…catch…,可参考:详解C++异常处理使用方法
三.nothrow常量
nothrow是一个常量,定义再 < new >头文件中,当我们使用new申请内存空间时,将其做参数传入,就能使得申请空间失败时,返回空指针NULL,而不是抛出std::bad_alloc异常。
见下面的简单例子:
// nothrow example
#include <iostream> // std::cout
#include <new> // std::nothrow
using namespace std;
int main()
{
double * ptr[50];
for (int i = 0; i<50; i++)
{
ptr[i] = new(nothrow) double[50000000];
if (ptr[i] == NULL)
{
cout << "new error" << endl;
system("pause");
exit(1);
}
cout << "ptr[" << i << "]" << "->50000000 duble" << endl;
}
system("pause");
return 0;
}
结果如下:
以上就是全部的内容,如果有疑问,欢迎评论区下方留言;本人水平有限 ,如有错误,也欢迎在评论区下方批评指正。若是喜欢本文,就帮忙点赞吧!