指针作为C++迭代器
pointer as C++ iterator
几天前,我看到了这样的代码:
#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);
}
除了使用auto
和constexpr
之外,该代码在C++11
、C++
甚至在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;
之前被中断。
循环就是这样运作的。
- 执行语句
auto it = x;
- 执行语句
std::cout << *it << std::endl;
- 执行语句
++it
- 如果表达式
it < x + max
的计算结果为true,则返回(2)
当it == x + max
时,循环在(4)上中断,而不跳回(2)并取消引用该悬挂指针。
不,这段代码不会按照你说的去做。没有对经过结束元素的元素进行访问。
有一个指向这样一个元素的指针是合法的(毕竟,这就是C++中所有迭代器范围的工作方式),但不去引用它(除非它与std::string
有关;那么就保证了CharT()
)。但你也不这样做,所以没关系。
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 我可以使用反向迭代器作为ForwardIt吗
- ESP8266单片机矢量迭代器的C++问题
- 如何在C++中将迭代器作为函数参数传递
- 是否应避免从非常量迭代器转换为常量迭代器?
- 如何在 c++ 中将字符串迭代器变量传递给函数?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?