使用通用迭代器访问数组的数组元素 [英] Access to elements of array of arrays using common iterator

查看:267
本文介绍了使用通用迭代器访问数组的数组元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用下面的代码访问相邻数组中的元素是否是C ++中的未定义行为?

Is it undefined behaviour in C++ to access elements in adjacent arrays as in following code?

#include <type_traits>
#include <algorithm>
#include <iterator>

int main()
{
    int a[10][10];
    static_assert(std::is_standard_layout< decltype(a) >::value, "!");
    std::fill(std::begin(*std::begin(a)), std::end(*std::prev(std::end(a))), 0);
    struct B { int b[10]; };
    B b[10];
    static_assert(std::is_standard_layout< decltype(b) >::value, "!");
    std::fill(std::begin(std::begin(b)->b), std::end(std::prev(std::end(b))->b), 0);
}

从技术上讲,我认为对于POD类型,以一种想要的方式访问基础内存是合法的,但是std::*的东西呢?

Technically I think for POD-types it is legal to access underlying memory in any manner one want, but what about std::* stuff?

如果我将所有begin/end都更改为rbegin/rend怎么办?

What if I change all begin/end to rbegin/rend?

推荐答案

是的,这是UB.

来自 [basic.compound] :

指针类型的每个值都是以下之一:

Every value of pointer type is one of the following:

  • 指向对象或函数的指针(据说该指针指向该对象或函数),或者
  • 超出对象末尾的指针([expr.add]),或
  • 该类型的空指针值([conv.ptr]),或
  • 无效的指针值.
  • a pointer to an object or function (the pointer is said to point to the object or function), or
  • a pointer past the end of an object ([expr.add]), or
  • the null pointer value ([conv.ptr]) for that type, or
  • an invalid pointer value.

指针类型的值,该指针类型是指向或超过对象末尾的指针,表示该对象占用的内存中第一个字节([intro.memory])的地址或结束后内存中的第一个字节的地址对象占用的存储空间的百分比. [注:超出对象末尾的指针([expr.add])不被认为指向可能位于该地址的对象类型的不相关对象.当指针值指示的存储到达其存储持续时间的结尾时,该指针值将变为无效;否则,指针值将变为无效.参见[basic.stc]. -注释]

A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory ([intro.memory]) occupied by the object or the first byte in memory after the end of the storage occupied by the object, respectively. [ Note: A pointer past the end of an object ([expr.add]) is not considered to point to an unrelated object of the object's type that might be located at that address. A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration; see [basic.stc]. — end note ]

[expr.add]/4 :

当将具有整数类型的表达式添加到指针或从指针中减去时,结果将具有指针操作数的类型.如果表达式P指向具有n个元素的数组对象x的元素x [i] 86,则表达式P + J和J + P(其中J的值为j)指向元素x [i + j]如果0≤i+j≤n;否则,行为是不确定的.类似地,如果0≤ij≤n,则表达式P-J指向(可能是假设的)元素x [ij];否则,行为是不确定的.

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements,86 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n ; otherwise, the behavior is undefined.

所以&a[0][0] + 10是对象末尾的指针",它是第一个数组的末尾指针.您不能再向该指针添加一个-在这种情况下没有定义的行为.

So &a[0][0] + 10 is a "pointer past the end of an object", it's the past the end pointer of the first array. You cannot add one more to that pointer - there is no defined behavior for this case.

指针不能同时是"结束"指针和 指向对象的指针"(将&a[0][0] + 10解释为&a[1][0]).是一个或另一个.

A pointer cannot be both a "past the end" pointer and a "pointer to object" (interpreting &a[0][0] + 10 as if it were &a[1][0]). It's one or the other.

这篇关于使用通用迭代器访问数组的数组元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆