c – 向量复制/移动分配时底层存储器会发生什么?

前端之家收集整理的这篇文章主要介绍了c – 向量复制/移动分配时底层存储器会发生什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
对于std :: vector的副本分配,当源的大小小于目标的容量时,是否重新分配容量的容量和容量的缩小?还是保证重新分配/收缩不会发生(即始终尊重以前的储备())?

另一方面,如果源的大小大于目的地的容量并进行重新分配,是否要求重新分配与源的容量相关(例如,目的地的新容量应不小于源的容量,甚至要求它们相同)?或者重新分配只是根据新的规模完成工作(不考虑源的容量)

对于移动分配,我认为不会进行存储重新分配(虽然我没有找到标准中的相关部分),但是这意味着目标的新容量的价值将与源的旧容量完全相同?我可以期待v = vector< T> {};具有与矢量< T> {}相同的效果.swap(v);?

我想这个答案被埋在标准的某个地方,但是我没有找到它们.
(如果C 11和C 03的情况不同,我想了解两者的各种要求.)

PS:对于上述问题的任何答案,对于std :: string(仅在C 11中意思是连续存储,没有COW,C 03字符串不在雷达中)是否相同?

解决方法

std::vector<T,A>( std::vector<T,A>&& )

这被保证是恒定的时间(N3797表99 X u(rv)).

没有任何方法可以自己移动一个任意大小的向量在不变的时间,而不必将指针移动到缓冲区.如果这样(没有办法)为真,则构造的向量必须至少具有与源缓冲区一样大的缓冲区.标准中没有任何措辞说明向量需要有效,但右手侧向量可以将其容量减小到大于或等于其大小的任何值:后置条件只是元素相同.在理论上,如果右手侧的向量具有编译器选择暴露的“隐藏能力”,那么甚至可能是更大的容量(说明月球的阶段).

N3797标准中的任何一点都不是放在任何容器上的容量的上限.一致的实现可以使所有的std ::向量具有至少200万的元素容量(禁止分配器失败 – 可以用来强制容量为0),没有操作能够将该值降低到200万以下. (shrink_to_fit只是一个建议,std :: vector< T,A>().swap(x)可以创建200万容量的向量并进行交换.

上面所说的都是一个负面的形式,我可以说是搜索标准,以提供向量,分配器,分配和容量.容量在任何时候都不会用上限描述.在空std :: vector构造函数中,对分配器的额外调用没有限制(如果分配器失败,则可能需要保持0和容量0,但是将该状态提取到使用相同的分配器是具有挑战性的).

对于副本分配和移动分配,副本分配不会超出最基本的(该容量()> = size())的容量保证.

对于移动分配,这取决于如何适用:

23.2.1 [container.requirements.general] / 10

Unless otherwise specified (either explicitly or by defining a function in terms of other functions),invoking a
container member function or passing a container as an argument to a library function shall not invalidate
iterators to,or change the values of,objects within that container.

表96和表99中的a = rv(aka std :: vector< T,A>& operator =(std :: vector< T,A>&&&&没有提到rv中包含的值被破坏,也不会使对它们的迭代器无效.因此,在23.2.1 / 10下,迭代器不会失效.

但是,这并不要求缓冲区移动.缓冲区从rhs移动到lhs,或者在rhs载体中保持完整.表99提到这种情况,当它表示lhs项目可以移动分配给(这是std ::数组可以工作的唯一方式)时,这是隐含的.

由于std ::数组不得不移动元素,而std :: vector对移动缓冲区没有任何进一步的保证,缓冲区不必被移动.看来,移动缓冲区是一种合法的实现.

在实践中,A>(std :: vector< T,A> const&)将执行右侧内容的副本进入左侧,左侧的容量等于所得到的矢量的大小.类似地,A>(ForwardIterator,ForwardIterator)将产生适合其输入的向量.

注意,A> :: operator =(std :: vector< T,A>&&)在复杂性中保持线性.

猜你在找的C&C++相关文章