STD ::向量如何调整其内部缓冲区大小

How does std::vector resize its internal buffer?

本文关键字:内部 缓冲区 向量 何调整 STD 调整      更新时间:2023-10-16

据我所知,c 不支持诸如c语言的'realloc(void *,size_t(之类的操作员。

但是,std :: vector应该有一个缓冲区以包含数据,并且应扩展或压实缓冲区。

那么,如何在没有'realloc'函数的情况下调整std :: vector的缓冲区大小?

仅通过分配新的缓冲区,复制或移动所有元素并破坏以前的缓冲区而完成?我认为这是低效的。

据我所知,C 不支持诸如'realloc(void *,size_t('

之类的操作员

C 确实具有std::realloc。但这不是(通常是?(用于实施向量的调整大小。

那么,如何在没有'realloc'函数的情况下调整std :: vector的缓冲区大小?

使用以下算法:

  • 分配新数组
  • 复制或将内容移至新数组
  • DealLocate Old Array

仅通过分配新的缓冲区,复制或移动所有元素并破坏以前的缓冲区?

来完成?

是。

我认为这是低效的。

你为什么这么认为?恰好 realloc做什么。当然,realloc May 有时能够根据内存布局跳过复制,该向量通常不能。与手动malloc ATED动态阵列相比,这是向量的不幸缺点,但这不一定是一个重要的缺点。

已提出建议在标准分配器中添加重新分配支持,如果采用到标准中,则可以进行相同的优化:http://open-std.org/jtc1/sc1/sc2222222221/wg21/docs/papers/papers/2019/p0894r1.md

std :: realloc是从不使用,除非容器知道对象是琐碎的。

来源:https://en.cppreference.com/w/cpp/memory/c/realloc

因为重新分配可能涉及串行复制(无论如何 无论是扩展还是收缩(,只有 在保存的部分中,可易于仔细的类型可以安全地访问 通话后的内存块。

一些非标准库定义了类型特征" bitwisemovable"或 "可重新定位",它描述了没有:

的类型

如果容器不知道对象是微不足道的共配,则使用Realloc扩展内存可能会导致损坏的数据。

如果可以在容器上使用is_trivaly_copiable,则可以使用realloc。否则将导致不确定的行为。

否则,容器a(创建新内存,b(调用元素的复制或移动构造函数,以将其移动到新内存c(释放旧内存。

在理论上是std::vector<bool>的情况下,内部使用了相当于 realloc 的事实,但要查看G 的实现(GCC版本6.3(.0 20170516/raspbian(:

  template<typename _Alloc>
    void
    vector<bool, _Alloc>::
    _M_reallocate(size_type __n)
    {
      _Bit_pointer __q = this->_M_allocate(__n);
      iterator __start(std::__addressof(*__q), 0);
      this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), __start);
      this->_M_deallocate();
      this->_M_impl._M_start = __start;
      this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
    }

因此,它基于新的分配,然后复制然后DealLocation

std :: vector 具有一个调整大小函数,使您可以根据需要扩展或压实数组。如果确实发生了重新分配,则将元素复制/移动到新的分配。这是迭代器可能无效的原因。