分配存储UB上的指针算术运算吗?

问题描述 投票:1回答:1

假设我想在不调用任何未定义行为(UB)的情况下实现std :: vector。下面的代码是否调用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)指向(possible-hypothetical)元素x [i + j]如果0 <= i + j <= n;否则,行为是不确定的。同样,表达式P-J指向(可能假设)元素x [i-j]如果0 <= i-j <= n;否则,行为是不确定的。

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

c++ memory-management language-lawyer
1个回答
1
投票

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

[短语“可能是假设的”指的是过去的“要素”(ref),不允许这种情况。

© www.soinside.com 2019 - 2024. All rights reserved.