vector和指针的可预测性

std::vector and pointer predictability

本文关键字:可预测性 指针 vector      更新时间:2023-10-16

当您将push_back()项放入std::vector,并通过back()引用保留指向向量中对象的指针时,您保证(假设没有删除发生)向量中对象的地址将保持不变吗?

似乎我的向量改变了我使用的对象的指针,这样,如果我将10个项目推入其中,并通过记住每个push_back之后的back()引用来保留指向这10个项目的指针。

如果你的vector是存储对象,而不是对象指针,这些对象的地址是否在推入更多项时不断变化?

任何导致vector对象自身大小调整的方法都会使vector对象中所有迭代器、指针和对vector对象中所含元素的引用失效。这可以通过保留内存或使用boost::stable_vector来避免。

23.3.6.5/1:

备注:如果新容量大于旧容量,会导致重新分配。如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。

不,std::vector不是一个稳定的容器,即指针和迭代器可能会通过调整vector的大小(或者更好的是通过相应的重新分配)而失效。如果您想避免这种行为,请使用boost::stable_vectorstd::liststd::deque代替(我更喜欢最后一个)。或者,更简单的是,您可以简单地通过索引存储您的位置。

要了解更多信息,也可以考虑这里对这个问题的回答

不能保证。如果push_back的项数超过了vector的后端存储内存缓冲区的大小,则会创建一个新的缓冲区,将所有内容复制到新的位置,并删除旧的缓冲区。此时,旧指针(以及迭代器!)将无效。

如果你确切地知道你将需要多少最大空间,你可以在创建vector的缓冲区时将其大小设置为该大小,以避免重新分配。但是,我更喜欢将对vector元素的"引用"存储为对vector的引用,并将size_t索引存储为vector的索引,而不是使用指针。它不一定比指针慢(取决于CPU类型),但是,即使是,它也不会慢很多,在我看来,这是值得的,因为知道无论将来如何使用或重新分配向量,它仍然指向正确的元素。