本文介绍了为什么std :: nothrow在gcc(4.9)中按预期工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
SomeClass * pSc = new SomeClass;我的团队中有很多人检查这样的空指针。
if(NULL == pSc)
{
//应付错误
}
我知道这是行不通的,因为c ++中的new运算符抛出std :: bad_alloc异常而不返回NULL。我也知道std :: nothrow可以使他们预期的真正发生。所以我写了一个这样的例子:
#include< iostream>
#include< limits>
#include< new>
使用namespace std;
void myNewHandler()
{
std :: cerr<< 无法分配内存! <<的std :: ENDL;
$ b $ int main(int argc,char * argv [])
{
// std :: new_handler oldHandler = std :: set_new_handler(myNewHandler);
int * pLotsMem = new(std :: nothrow)int [std :: numeric_limits< long long> :: max()];
if(nullptr == pLotsMem)
{
std :: cerr<< 分配失败<<的std :: ENDL;
返回-1;
}
else
{
delete [] pLotsMem;
pLotsMem = nullptr;
}
// std :: set_new_handler(oldHandler);
返回0;
}
是的,我想演示std :: set_new_handler的用法。令我惊讶的是,即使这样也行不通。 new运算符仍然抛出一个异常(std :: bad_array_new_length,std :: bad_alloc派生类),然后终止程序。
任何想法为什么这不起作用? gcc中新操作符返回的指针应该如何检查?
解决方案相信与否,这是符合标准的行为:
简而言之,非抛出分配器函数甚至没有被调用,异常是由 new-expression 本身抛出的。
我假设你没有使用现代C ++版本,因为在 std :: numeric_limits< long long> :: max()
标记为 constexpr
,它是一个核心常量表达式,它会产生编译时错误。
Clang,很可能有实现定义的限制设置为高于long long的最大值,绕过了C ++的这个怪癖。
I've seen lots of people in my team checking null pointers like this:
SomeClass *pSc = new SomeClass;
if ( NULL == pSc )
{
// cope with error
}
I known this will not work, because new operator in c++ throws a std::bad_alloc exception instead of returning NULL. I also know that std::nothrow can make what they expected really happen. So I wrote an example like this:
#include <iostream>
#include <limits>
#include <new>
using namespace std;
void myNewHandler()
{
std::cerr << "Failed to allocate memory!" << std::endl;
}
int main(int argc, char* argv[])
{
//std::new_handler oldHandler = std::set_new_handler(myNewHandler);
int *pLotsMem = new(std::nothrow) int[std::numeric_limits<long long>::max()];
if ( nullptr == pLotsMem )
{
std::cerr << "Allocation failed" << std::endl;
return -1;
}
else
{
delete[] pLotsMem;
pLotsMem = nullptr;
}
//std::set_new_handler(oldHandler);
return 0;
}
Yes, I wanted to demonstrate usage of std::set_new_handler as well. To my surprise, even this did not work. new operator still threw an exception(std::bad_array_new_length, a derived class of std::bad_alloc) and then terminated the program.
Any idea why this failed to work? How should one check pointers returned by new operator in gcc?
解决方案
Believe or not, this is standard compliant behavior:
In short, non-throwing allocator function is not even called, exception is thrown by new-expression itself.
I assume that you are not using modern C++ version, because in those std::numeric_limits<long long>::max()
marked as constexpr
and is a core constant expression, which yields compile-time error.
Clang, probably has implementation-defined limit set higher than max value of long lond, bypassing this quirk of C++.
这篇关于为什么std :: nothrow在gcc(4.9)中按预期工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!