减法或减法随机访问迭代器指向开始 [英] Substraction or decrement random access iterator pointing to begin

查看:15
本文介绍了减法或减法随机访问迭代器指向开始的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的代码

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() 时被减去.如果可以的话,我找不到任何地方,直到我不取消引用这个错误的指向迭代器).

As you can see there is some doubt when forward == false becouse there is an substraction from begin() and iterator it can be substracted when it points at begin(). I can't find anywhere if it is ok until I not dereference this bad pointing iterator).

编辑

我阅读了 ISO C++ 标准并得出了一些结论.没有保证 vector::begin() 不能内部指向地址 0 处的内存,我在想它是结束,但所有容器都依赖在标准分配器上.这个分配器依赖于 new 操作符.而且,没有信息表明 new 永远不会返回 0.但是标准分配器也依赖于 delete 操作符,如果你传递 0,这个操作符应该什么也不做.因此,根据这个事实, new 不能返回 0 因为没有办法删除该指针,因此,非空 vector无法返回指向 0begin().

I read ISO C++ Standard and have some conclusions. There is no promise that vector::begin() can't internaly point to memory at adress 0, and I was thinking that It is the end, but all containers depend on standard alocator. This alocator depends on new operator. And also, there is no information that new will never return 0. But standard alocator depends also on delete operator and this operator is supose to do nothing if you pass 0. So by this fact, new can't return 0 becouse there will be no way to delete that pointer, and by that, non empty vector can't return begin() that points to 0.

结论:

如果上面是指向 vector::begin() 的右递减插入器应该是安全的,因为 vector 的内部存储器是连续的.

If above is right decrementing interator that points at vector::begin() should be safe, since internal memory of the vector is continouse.

我说的对吗?

终极答案

即使它现在有效并且将来会有效,根据标准,它也是未定义的行为.如果您这样做,您将自行承担风险.看到这个类似的问题更多信息.

Even if it works now and will be working in the future it is undefined behavour according to the standard. If you do this, you are doing this on your own risk. See this simmilar question for more informations.

推荐答案

你不能递减传递给 begin 的迭代器,也不能计算 begin() - 1.

You cannot decrement an iterator passed begin, or compute begin() - 1.

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

While the implementation is required to have a position for one passed the last element, it is not required to have any address space available before begin. So begin() - 1 might not be a valid address (and definitely not a valid iterator).

关于第 2 题:

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

Even though if (p == 0) tests if the pointer is null, that doesn't mean that a null pointer has to be represented by all bits zero. It could also be all bits 1, or something else. Compiler magic will make the test work anyway.

另一个无效地址的例子是,当您释放一大块内存时,堆管理器可能也可能从您的进程中删除相应的虚拟地址空间.

Another example of an invalid address is that when you deallocate a large block of memory, the heap manager just could possibly also remove the corresponding virtual address space from your process.

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

Another memory block starting just after the deallocated space could then have an address, say, 0x10000 where the address 0x10000 - 1 does no longer exist. Some hardware, which uses dedicated address registers for pointers, is known to trap when loading an invalid pointer. It just could detect that 0x10000 - 1 isn't mapped to RAM anymore and abort your program. The standard is written to allow this, because such hardware exists.

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

We don't say that this is what normally happens on common desktop operating systems, just what could happen according to the language standard.

这篇关于减法或减法随机访问迭代器指向开始的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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