gpt4 book ai didi

c++ - 减法或递减指向开始的随机访问迭代器

转载 作者:行者123 更新时间:2023-11-30 00:57:16 25 4
gpt4 key购买 nike

考虑以下代码

void foo( bool forwad )
{
vector<MyObject>::iterator it, end_it;
int dir;

it = some_global_vector.begin() + some_position;
if( forward )
{
dir = 1;
it += 1;
end_it = some_global_vector.end();

}
else
{
dir = -1;
it -= 1;
end_it = some_global_vector.begin()-1;
}

while( it != end_it )
{
if( do_domething() )
break;

it += dir;
}
}

如您所见,当 forward == false 时存在一些疑问,因为 begin() 和迭代器 it 可以进行减法当它指向 begin() 时被减去。在我不取消引用这个错误的指向迭代器之前,我找不到任何地方是否可以。

编辑

我阅读了 ISO C++ 标准并得出了一些结论。没有 promise vector::begin() 不能在内部指向地址 0 处的内存,我当时认为这是结束,但所有容器都取决于在标准分配器上。这个分配器依赖于 new 运算符。而且,没有任何信息表明 new 永远不会返回 0。但标准分配器还依赖于 delete 运算符,如果您传递 0,该运算符应该什么也不做。所以根据这个事实,new 不能返回 0 因为没有办法删除那个指针,因此,非空的 vector无法返回指向 0begin()

结论:

如果上面是正确的,指向 vector::begin() 的递减 interator 应该是安全的,因为 vector 的内部存储器是连续的。

我说得对吗?

最终答案

即使它现在可以工作并且将来也可以工作,但根据标准,它是未定义的行为。如果您这样做,您将自行承担风险。看到这个类似的 question 了解更多信息。

最佳答案

您不能递减通过 begin 的迭代器,或计算 begin() - 1

虽然实现需要为最后一个元素指定一个位置,但在开始之前不需要有任何可用的地址空间。所以 begin() - 1 可能不是一个有效的地址(而且绝对不是一个有效的迭代器)。


关于问题 2:

尽管 if (p == 0) 测试指针是否为空,但这并不意味着空指针必须由所有位表示为零.它也可以是所有位 1,或其他。无论如何,编译器的魔力都会让测试成功。

无效地址的另一个示例是,当您取消分配大块内存时,堆管理器可能也可能从您的进程中删除相应的虚拟地址空间。

在释放空间之后开始的另一个内存块可以有一个地址,比如 0x10000,其中地址 0x10000 - 1 不再存在。已知某些使用专用地址寄存器作为指针的硬件在加载无效指针时会陷入陷阱。它只是可以 检测到0x10000 - 1 不再映射到RAM 并中止您的程序。编写标准是为了允许这样做,因为存在这样的硬件。

我们并不是说这是常见桌面操作系统上通常发生的情况,只是根据语言标准可能发生的情况。

关于c++ - 减法或递减指向开始的随机访问迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8533875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com