恒定时间访问是否​​意味着在某些时候连续的内存?

时间:2017-12-10 19:55:06

标签: c++ c c++11 iterator undefined-behavior

正如标题所说,我想知道常量时间/ O(1)对容器的访问是否意味着内存在某些点必然是连续的。 当我说连续时,我的意思是指针可以在某些时候与关系运算符进行比较,而不会调用未定义的行为。

std :: deque 为例:它不保证所有元素都是连续存储的(即在同一个内存数组中),但是说std​​ :: deque满足是正确的 随机访问迭代器 的要求,内存在某些时候是连续的,与实现无关?

我是C ++的新手,所以如果我上面说的话没有意义:假设我要在C中实现随机访问迭代器。

typedef struct random_access_iterator {
    void *pointer; /*pointer to element */
    void *block; /* pointer to the memory array
                  * so in case of comparing iterators
                  * where pointer does not point to addresses in the same array
                  * it can be used to comparisons instead*/
    /* implement other stuff */
} RandomIter;

用于泛化表达与C ++随机访问迭代器类似的机制(考虑到即使指针没有,块总是会  指向同一容器的迭代器中相同内存数组中的地址)?

编辑:只是为了澄清,此处的常数时间用于表示恒定时间随机访问

1 个答案:

答案 0 :(得分:2)

没有。考虑一个固定大小的链表,如下所示:

struct DumbCounterexample
{
    struct node
    {
        std::vector<int> items;
        std::unique_ptr<node> next;
    };

    std::unique_ptr<node> first;
    size_t size;
    static constexpr size_t NODE_COUNT = 10;

    DumbCounterexample()
        : first{new node},
          size{0}
    {
        node* to_fill = first.get();
        for (size_t i = 0; i < NODE_COUNT - 1; ++i) {
            to_fill->next.reset(new node);
            to_fill = to_fill->next.get();
        }
    }

    int& operator[](size_t i)
    {
        size_t node_num = i % NODE_COUNT;
        size_t item_num = i / NODE_COUNT;
        node* target_node = first.get();
        for (size_t n = 0; n < node_num; ++n) {
            target_node = target_node->next.get();
        }
        return target_node->items[item_num];
    }

    void push_back(int i)
    {
        size_t node_num = size % NODE_COUNT;
        node* target_node = first.get();
        for (size_t n = 0; n < node_num; ++n) {
            target_node = target_node->next.get();
        }
        target_node->items.push_back(i);
        ++size;
    }

};

查找时间不变。它不依赖于容器中存储的元素数量(只有常量NODE_COUNT)。

现在,这是一个奇怪的数据结构,我无法想到使用它的任何合理理由,但它确实可以作为一个反例,声称需要一个可以共享的单个连续内存块。通过容器中元素的所有迭代器(即示例block结构中的random_access_iterator指针)。