指针作为C++迭代器

pointer as C++ iterator

本文关键字:迭代器 C++ 指针      更新时间:2023-10-16

几天前,我看到了这样的代码:

#include <iostream>
void test(const int *x, int max){
    for(auto it = x; it < x + max; ++it)
        std::cout << *it << std::endl;
}
int main(){
    constexpr int MAX = 5;
    constexpr int x[MAX] = { 1,2,4,5,7 };
    test(x, MAX);
}

除了使用autoconstexpr之外,该代码在C++11C++甚至在C中都可以正常工作。

然而,有一些东西困扰着我——代码访问最后一个元素之后的元素,例如-x[5]。我相信在某些情况下,这可能是地址冲突,例如,如果你mmap()一些内存,并试图在你的mmap-ed之后读取内存。另一种可能性是,如果数组是在只读内存中分配的。

我的假设正确吗?我知道我错了,但为什么?

我记得在C++标准中读到,在数组的最后一个元素后面有一个指向1的指针是有效的(在这种情况下是&x[5]),但它从来都不是有效的

显示的代码似乎从来没有尊重它(它只在it < x + max时取消引用*它),但x + max只是&x[max] = &x[5],根据C++标准,它是有效的,但由于代码从未取消引用这个值,所以代码很好,工作正常。

注意:永远不要试图取消引用像x[max]这样的东西,这是标准中未定义的行为,可能会发生不好的事情(崩溃或更糟…)

当条件it == x+max达到时,循环在执行行std::cout << *it << std::endl;之前被中断

循环就是这样运作的。

  1. 执行语句auto it = x;
  2. 执行语句std::cout << *it << std::endl;
  3. 执行语句++it
  4. 如果表达式it < x + max的计算结果为true,则返回(2)

it == x + max时,循环在(4)上中断,而不跳回(2)并取消引用该悬挂指针。

不,这段代码不会按照你说的去做。没有对经过结束元素的元素进行访问。

有一个指向这样一个元素的指针是合法的(毕竟,这就是C++中所有迭代器范围的工作方式),但不去引用它(除非它与std::string有关;那么就保证了CharT())。但你也不这样做,所以没关系。