当新操作员失败时的构造函数调用
我正试图实施一项技术来测试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中的做法。
但是,VArray
的构造函数仍然在GCC中失败的new
之后调用。并且因为this
是NULL
,它会在第一次分配给属性时产生SIGSEGV。这似乎是错误的行为根据C + + 03标准:https://*.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);
}
我想念什么?
C++标准要求分配函数(如基本operator new
)通过抛出std::bad_alloc
异常(如果失败)而失败。不允许返回空指针。当你返回一个空指针时你有未定义的行为,是的,一个可能的结果是调用构造函数。
感谢您的提示,但我的初衷是替换'新(std :: nothrow)',我同意我已经完成了一半。所以你帮我正确完成了。 – Melebius 2014-10-20 09:18:36
如果被调用的operator new
被声明为throw()
,那么 编译器不检查空指针是错误的。 但是声明非放置的新文件throw()
是非法的,所以 编译器检查它没有意义;如果有的话, 应该在看到声明时发出抱怨,因为 非放置operator new
被隐式声明。
如果你想测试未能new
(这是一个好主意), 您operator new
函数不应该返回一个空指针, 但应该抛出std::bad_alloc
。否则,你不是 测试同样的事情。在您网站的页面上,测试代码 使用新的展示位置。该代码仍然是非法的, ,因为他的operator new
可能会返回一个空指针而没有 宣布功能throw()
,但很容易 固定。 (或不他呼吁::operator new
,而不是 malloc
,对于实际分配,而这个功能可能 扔他还呼吁::operator new
函数来分配, 但使用的::delete
运营商去免费;如果你调用 ::operator new
)当然,即使是固定的,它也不会测试 任何有用的东西,因为你需要知道的是,你的 程序对std::bad_alloc
反应正确,而不是它对 正确反应空指针,它永远不会看到。
谢谢您对原始示例的彻底检查。是的,我修改了它,因为放置'new'不是我想测试的东西。由于我正在替换“基本”全局'new',所以我无法调用':: operator new',因为它被替换!这就是'malloc'和'free'的原因。 – Melebius 2014-10-20 09:28:59
替换'operator new'必须在失败时抛出'std :: bad_alloc'。返回NULL值违反了合同。“需要的行为:返回一个非空指针到合适对齐的存储区(3.7.4),否则抛出一个'bad_alloc'异常。**这个需求绑定到这个函数的替换版本**上。 – 2014-10-20 08:50:56