std :: set是否将对象连续存储在内存中?


16

是否std::set将对象存储在连续内存中std::vector

我一直无法在网上找到它,cppreference并未提及有关内存分配的详细信息。但是我看不到为什么它不能使用连续内存,因此我提出了问题。


5
阅读set::insert要求:en.cppreference.com/w/cpp/container/set/insert “ ...没有迭代器或引用无效....”,因此当它需要像扩展时一样无法重新分配std::vector
理查德·克里顿

性能:对于您的用例,您需要进行衡量(取决于您的哈希函数),请参阅:channel9.msdn.com/Events/Build/2014/2-661 from 45:48
Richard Critten

4
另请参见boost :: flat_set
卡雷斯

1
您是说“连续的”,如“迭代集合时,对象存储在连续的内存位置中”,还是“所有的对象都存储在一大块内存中(但以任意顺序)”?
Pablo H

1
通常,当您问“容器A是否与容器B相同”时,答案是“否”,否则只会存在容器A(因为拥有容器B的目的是什么?)。当然,这不适用于容器适配器,但std::set不是其中之一,这是关键。
在轨道进行的轻度比赛

Answers:


25

std :: set是否将对象存储在像std :: vector这样的连续内存中?

无法保证确实如此。同样在实践中,由于容器的要求,它不能。因此,否,它不会将对象存储在连续内存中。

我不明白为什么它不能使用连续内存

对集合元素的引用在插入和删除时必须保持有效(对已删除元素的引用除外)。此要求与连续内存不兼容。

据我所知,平衡的搜索树是唯一可以实现的数据结构std::set


万一这就是OP的意思,它可以为大型连续块中的树节点分配空间。(但是没有迭代器失效会排除insert将所有节点复制到一个更大的新块中的情况,以将其限制为一个块,以防就地重新分配失败或(对于C ++通常)分配器不支持这种重新分配。)
Peter Cordes

15

它没有明确地排除在外,尽管某些约束std::set使得不可能使用连续内存。

例如,set::insert具有对数复杂度,而vector::insert需要线性复杂度以改组其条目。也set::insert不会失效迭代器。这两个要求不能用连续存储器来实现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.