2014-10-20 31 views
1

我正试图实施一项技术来测试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之后调用。并且因为thisNULL,它会在第一次分配给属性时产生SIGSEGV。这似乎是错误的行为根据C + + 03标准:https://stackoverflow.com/a/11514528/711006

我的实施运营商newdelete下面。

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); 
} 

我想念什么?

+6

替换'operator new'必须在失败时抛出'std :: bad_alloc'。返回NULL值违反了合同。“需要的行为:返回一个非空指针到合适对齐的存储区(3.7.4),否则抛出一个'bad_alloc'异常。**这个需求绑定到这个函数的替换版本**上。 – 2014-10-20 08:50:56

回答

3

C++标准要求分配函数(如基本operator new)通过抛出std::bad_alloc异常(如果失败)而失败。不允许返回空指针。当你返回一个空指针时你有未定义的行为,是的,一个可能的结果是调用构造函数。

+0

感谢您的提示,但我的初衷是替换'新(std :: nothrow)',我同意我已经完成了一半。所以你帮我正确完成了。 – Melebius 2014-10-20 09:18:36

1

如果被调用的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反应正确,而不是它对 正确反应空指针,它永远不会看到。

+0

谢谢您对原始示例的彻底检查。是的,我修改了它,因为放置'new'不是我想测试的东西。由于我正在替换“基本”全局'new',所以我无法调用':: operator new',因为它被替换!这就是'malloc'和'free'的原因。 – Melebius 2014-10-20 09:28:59

相关问题