为什么std::nothrow在gcc(4.9)中没有按预期工作
Why does not std::nothrow work as expected in gcc(4.9)?
我看到我的团队中有很多人检查这样的空指针:
SomeClass *pSc = new SomeClass;
if ( NULL == pSc )
{
// cope with error
}
我知道这不会起作用,因为c++中的新运算符抛出std::bad_alloc异常,而不是返回NULL。我也知道std::没有什么能让他们期望的事情真正发生。所以我写了一个这样的例子:
#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;
}
是的,我也想演示std::set_new_handler的用法。令我惊讶的是,即使这样也没有奏效。new操作符仍然抛出异常(std::badArray_new_length,std::Badalloc的派生类),然后终止程序。
知道为什么这没能奏效吗应该如何检查gcc中新运算符返回的指针?
信不信由你,这是符合标准的行为:
5.3.4/7
如果:
[…]-其值使得分配对象的大小将超过实现定义的限制,则noptr新声明符中的表达式是错误的(附件B);或
[…]如果转换为std::size_t后的表达式是核心常量表达式和表达式是错误的,程序是不正确的。否则,带有错误表达式的新表达式不会调用一个分配函数并通过抛出的异常终止与类型的处理程序(15.3)匹配的类型std::bad_array_new_length(18.6.2.2)表达式为零,则调用分配函数来分配没有元素的数组。
简而言之,甚至不调用非抛出分配器函数,异常是由新表达式本身抛出的。
我假设您没有使用现代C++版本,因为在那些标记为constexpr
的std::numeric_limits<long long>::max()
中,它是核心常量表达式,这会产生编译时错误。
Clang,可能将实现定义的限制设置为高于long-lond的最大值,从而绕过C++的这一怪癖。
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 为什么std::nothrow在gcc(4.9)中没有按预期工作