当前位置: 首页 > 知识库问答 >
问题:

已分配存储上的指针算法是UB吗?

长孙智刚
2023-03-14

假设我想实现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

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

共有1个答案

艾国安
2023-03-14

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

短语“可能假设”是指一个过去的结尾“元素”(ref),不允许这种情况。

 类似资料:
  • 我想知道何时或是否必须删除此对象。下面是一个基本类对象Object.cpp的构造函数: 我知道在分配内存时,你应该在某个时候删除它,但是我在构造函数中分配了内存,并且想再次使用变量1和2,我什么时候删除它们?

  • 我有一个func添加两个NO并返回(a+B)。然后我创建了一个指向func的func指针。希望为该函数指针的数组分配内存并访问它们。代码如下。 我的问题是使用malloc的下面一行: 编译时,sizeof(add_2nos*)和sizeof(add_2nos)没有任何区别。如果有什么区别??另外,如果类型转换是必要的,而我正在分配相同类型的内存…?

  • 在用C进行编码练习时,我必须为指向结构()的指针分配内存,即使该结构可能已经预先为它分配了内存,否则我将得到“赋值到空指针”类型的错误。 我的假设是,如果指针要指向一个预先分配内存的结构,那么分配更多的内存将是冗余的?为了澄清,代码编译和运行都没有错误,只是搞不清楚为什么我需要分配内存来实现预期的行为。 这里有一个链接到一个要点,以了解完整的上下文。谢了!

  • 问题内容: 考虑到您可以(无法想到一种放置它的好方法,但是)在Go中操作指针,是否有可能像在C中那样执行指针算术,例如遍历数组?我知道循环对于这些事情来说现在很好,但是我很好奇是否可能。 问题答案: 否。来自“常见问题解答”: 为什么没有指针算术? 安全。如果没有指针算术,就有可能创建一种永远不会派生出不正确地址的语言。编译器和硬件技术已经发展到可以使用数组索引的循环与使用指针算术的循环一样高效的

  • 问题内容: 给定一个看起来像 如果要设置为1,则必须 有没有办法在一行中执行此操作而不必给我新值它自己的名字(在这种情况下)? 问题答案: 如邮件列表中所述,您可以执行以下操作: 然后 如果您必须经常这样做。内联(请参见输出),因此它应该几乎没有性能损失。