指针存储UB上的指针运算?

时间:2017-09-02 21:34:09

标签: c++ memory-management language-lawyer

让我们说我想实现std :: vector而不调用任何未定义的行为(UB)。以下代码是否调用UB:

struct X{int i;};
int main(){
  auto p = static_cast<X*>(::operator new(sizeof(X)*2));
  new(p) X{};
  new(p+1) X{};// p+1 UB?
}

从标准中选择一些可能有用的引用:

[basic.stc.dynamic.allocation]

  

返回的指针(通过分配函数)应该适当地对齐,以便它可以转换为指向任何指针的指针   合适的完整对象类型(21.6.2.1)然后用于访问分配的存储中的对象或数组   (直到通过调用相应的释放函数显式释放存储空间。)

[expr.add]

  

当向指针添加或从指针中减去具有整数类型的表达式时,结果具有类型   指针操作数。如果表达式P指向具有n个元素的数组对象x的元素x [i],   表达式P + J和J + P(其中J的值为j)指向(可能假设的)元素   x [i + j]如果0 <= i + j <= n;否则,行为未定义。同样,表达式P - J指向   (可能假设的)元素x [i-j]如果0 <= i-j <= n;否则,行为未定义。

我的解释是,分配提供了一个可能假设的X数组(在C ++数组中是对象),因此在分配的存储上的指针算法可能不会调用未定义的行为。或者我对假设的解释是错误的?如果以前的代码snipest是UB,我该怎么办?

1 个答案:

答案 0 :(得分:1)

是的,从技术上讲,它具有不确定的行为,尽管我们倾向于忽略它。 P0593应该正确修复。

“可能是假设的”一词指的是“末尾”的“元素”(ref),不允许这种情况。