我正在尝试实施一种技术来测试http://www.codeproject.com/Articles/6108/Simulating-Memory-Allocation-Failure-for-Unit-Test中描述的失败的运算符new
。
这是一个正在测试的示例代码:
VArray* arr = new VArray(1U, 3U, true);
我可以让new
返回NULL
而不是分配内存。在这种情况下,程序应该继续下一行(应该测试是否arr == NULL
),这正是它在MSVC中的作用。
但是,在GCC中失败的VArray
之后仍然会调用new
的构造函数。由于this
是NULL
,因此在第一次分配属性时会产生SIGSEGV。根据C ++ 03标准,这似乎是一种错误的行为:https://stackoverflow.com/a/11514528/711006
我的运算符new
和delete
的实现如下。
unsigned int OperatorPlainNewFailsAfter = UINT_MAX;
void* operator new(const size_t _size) throw()
{
void* result;
if(OperatorPlainNewFailsAfter == 0U)
{
result = NULL;
}
else
{
result = malloc(_size);
OperatorPlainNewFailsAfter--;
}
return result;
}
void operator delete(void* _memory) throw()
{
free(_memory);
}
我想念什么?
答案 0 :(得分:3)
C ++标准要求分配函数(例如基本operator new
)通过抛出std::bad_alloc
异常(如果失败)而失败。它不允许返回nullpointer。当你确实返回一个nullpointer时,你有 Undefined Behavior ,是的,一个可能的结果就是调用了一个构造函数。
答案 1 :(得分:1)
如果被调用的operator new
被声明为throw()
,那么
编译器不检查空指针是错误的。
但声明非展示位置的新throw()
是违法的
编译器检查没有意义;如果有的话,它
当它看到声明时应该抱怨,因为
隐式声明非展示位置operator new
。
如果你想测试失败的new
(这是一个好主意),
你的operator new
函数不应返回空指针,
但应抛出std::bad_alloc
。否则,你不是
测试同样的事情。在您站点的页面上,测试代码
使用新的展示位置。代码仍然是非法的,
因为他的operator new
可能没有返回空指针
声明了函数throw()
,但这很容易
固定。 (或者不是。他称之为::operator new
,而不是
malloc
,对于实际分配,此函数可能
扔。他还调用::operator new
函数来分配,
但是使用::delete
运营商免费;如果你打电话
要::operator new
分配,你应该拨打::operator
delete
免费。)当然,即使是修复,也不会测试
任何有用的东西,因为你需要知道的是你的
程序对std::bad_alloc
的反应是正确的,而不是它
正确地响应它永远不会看到的空指针。