33

我有std::vector一些类的元素ClassA。此外,我想使用 a 创建一个索引,该索引std::map<key,ClassA*>将一些键值映射到指向向量中包含的元素的指针。

当在向量末尾添加元素(未插入)时,是否可以保证这些指针保持有效(并指向同一个对象)。即,以下代码是否正确:

std::vector<ClassA> storage;
std::map<int, ClassA*> map;

for (int i=0; i<10000; ++i) {
  storage.push_back(ClassA());
  map.insert(std::make_pair(storage.back().getKey(), &(storage.back()));
}
// map contains only valid pointers to the 'correct' elements of storage

如果我使用std::list而不是,情况如何std::vector

4

7 回答 7

28

向量 - 不。因为向量的容量永远不会缩小,所以可以保证即使删除或更改元素时引用、指针和迭代器仍然有效,前提是它们引用了被操作元素之前的位置。但是,插入可能会使引用、指针和迭代器无效。

列表 - 是的,插入和删除元素不会使指向其他元素的指针、引用和迭代器无效

于 2010-07-20T07:30:38.977 回答
9

据我了解,没有这样的保证。向向量添加元素将导致元素重新分配,从而使地图中的所有指针无效。

于 2010-07-20T07:28:28.890 回答
7

使用std::deque!指向元素的指针仅push_back()在使用时是稳定的。

注意:元素的迭代器可能会失效!指向元素的指针不会。

编辑:这个答案解释了为什么:C++ deque's iterator invalidated after push_front()

于 2010-07-20T07:52:10.970 回答
3

我不确定它是否得到保证,但实际上storage.reserve(needed_size)应该确保不会发生重新分配。

但是为什么不存储索引呢?
通过将索引添加到开始迭代器storage.begin()+idx&*(storage.begin()+idx)

于 2010-07-20T07:44:24.560 回答
1

从一个评论到另一个答案,似乎您想要的只是集中(简化)内存管理。如果情况确实如此,您应该考虑使用预打包的解决方案,例如boost 指针容器库,并让您自己的代码尽可能简单。

特别是,看看ptr_map

于 2010-07-20T08:35:17.637 回答
1

当您不需要它们时,只需让它们都存储指针并显式删除对象。

std::vector<ClassA*> storage;
std::map<int, ClassA*> map;

for (int i=0; i<10000; ++i) {
  ClassA* a = new ClassA()
  storage.push_back(a)
  map.insert(std::make_pair(a->getKey(), a))
}
// map contains only valid pointers to the 'correct' elements of storage
于 2010-07-20T07:31:24.450 回答
0
  1. 对于向量没有。
  2. 对于列表是的。如何?迭代器用作指向列表中特定节点的指针。因此您可以将值分配给任何结构,例如:

    列出我的清单;

    对< list::iterator ,int > temp;

    temp = make_pair( mylist.begin() , x );

于 2017-12-17T21:55:22.310 回答