当operator new失败时,构造函数调用

时间:2014-10-20 08:46:31

标签: c++ gcc c++03

我正在尝试实施一种技术来测试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的构造函数。由于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);
}

我想念什么?

2 个答案:

答案 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的反应是正确的,而不是它 正确地响应它永远不会看到的空指针。