正如标题所说,我想知道常量时间/ 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 ++随机访问迭代器类似的机制(考虑到即使指针没有,块总是会 指向同一容器的迭代器中相同内存数组中的地址)?
编辑:只是为了澄清,此处的常数时间用于表示恒定时间随机访问
答案 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
指针)。