C++将 2 个或更多地址超过数组末尾是否合法

C++ is it legal to take the address of 2 or more past the end of the array?

本文关键字:数组 是否 地址 C++      更新时间:2023-10-16

From 通过下标获取一个过去结束数组元素的地址:C++标准是否合法?

似乎有语言专门用于获取一个而不是数组端的地址。

如果不去引用,为什么 2 或 2000,000 过了最后会是一个问题?

看一些简单的循环:

int array[];
...
for (int i = 0: i < array_max; ++i)
{
       int * x = &array[i *2];      // Is this legal
       int y=0;
       if (i * 2 < array_max)       // We check here before dereference
       {
              y = *x;               // Legal dereference
       }
       ...
}

为什么或在什么时候变得未定义,在实践中它只是将 ptr 设置为某个值,如果不引用,为什么它会未定义?

更具体地说 - 除了预期会发生什么之外,还有什么例子可以?

将地址带到数组末尾之外的关键问题是分段体系结构:您可能会溢出指针的可表示范围。现有规则已经造成了一定程度的痛苦,因为这意味着最后一个对象不能位于段的边界上。但是,形成此地址的能力已经确立。

由于array[i *2]等价于*((array) + (i*2)),我们应该看看指针添加的规则。C++11 §5.7 说:

如果指针操作数和结果都指向同一数组对象的元素,或者指向数组对象的最后一个元素,则计算不应产生溢出;否则,行为是未定义的。

因此,即使您不在指针上执行间接寻址,您也有未定义的行为(更不用说您确实执行了间接寻址,因为我在开头给出了表达式等效性)。

实际上,它只是将PTR设置为某个值

从理论上讲,只允许使用指向无效位置的指针。

指针不是整数:它们是指向其他事物或空性的东西。

不能将它们设置为您喜欢的任何数字。

在此示例中,只有赋值,然后限定取消引用 - 该值仅在验证时才使用,问题是为什么值的设置是一个问题?

是的,你必须非常不幸才能遇到这样做的实际后果。"未定义的行为"并不意味着"总是崩溃"。为什么标准实际上应该强制要求此类操作的语义?你认为这样的语义应该是什么?