【问题标题】:std::vector and pointer predictabilitystd::vector 和指针可预测性
【发布时间】:2014-07-07 21:40:22
【问题描述】:

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

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

如果您的向量是存储对象,而不是指向对象的指针,那么这些对象的地址是否会在推送更多项目时不断变化?

【问题讨论】:

    标签: c++ vector std stdvector c++-standard-library


    【解决方案1】:

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

    23.3.6.5/1:

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

    【讨论】:

      【解决方案2】:

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

      如需了解更多信息,请同时考虑此问题的答案here

      【讨论】:

        【解决方案3】:

        无法保证。如果您 p​​ush_back 足够多的项目超过作为向量后备存储的内存缓冲区的大小,则会创建一个新缓冲区,所有内容将被复制到新位置,并且旧缓冲区将被删除。届时,旧指针(以及迭代器!)将无效。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-03-18
          • 1970-01-01
          • 2016-02-19
          • 1970-01-01
          • 1970-01-01
          • 2021-02-17
          • 2017-11-13
          相关资源
          最近更新 更多