如何以内存效率的方式缩小到适合std :: vector?

时间:2010-04-23 01:05:23

标签: c++ stl vector capacity

我想'缩小'适合'std::vector,将其容量减小到精确的大小,以便释放额外的内存。标准技巧似乎是here所描述的那个:

template< typename T, class Allocator >
void shrink_capacity(std::vector<T,Allocator>& v)
{
   std::vector<T,Allocator>(v.begin(),v.end()).swap(v);
}

缩小到适合的全部意义是节省内存,但是这种方法是不是首先创建一个深层副本然后交换实例?所以在某些时候 - 构建副本时 - 内存使用量是否翻了一倍?

如果是这种情况,是否有更适合内存的缩小方法? (在我的情况下,矢量非常大,我不能随时在内存中加上它的副本。)

2 个答案:

答案 0 :(得分:3)

好吧,如果你想调整数组的大小,你会怎么做?您必须创建一个新的并复制所有值 - 无论是单独还是使用memcpy或其他任何值。你不能真正用C或C ++调整数组大小。

std::vector几乎可以保证使用数组实现其存储(IIRC,标准不保证它是一个数组,但是数组是唯一可以满足API的各种要求的东西例如每个操作必须有多高效;因此,实际上即使该保证不明确也能保证。由于它是使用数组实现的,并且您无法在不复制的情况下调整数组大小,因此无法在不复制的情况下调整向量大小。

理论上,您可以使用shrink_capacity()函数来隐藏您必须暂时或多或少地将其大小要求加倍的事实,但由于std::vector目前没有这样的功能,必须实际制作一份明确的副本。交换技巧只是一种很好的方法。

如果在这种情况下你真的关心内存,你可以做的是使用指针(或智能指针),而不是让向量直接保存对象。这可能不是完全可取的,但它会降低你的内存需求。

答案 1 :(得分:-1)

如果您的新尺寸是原尺寸的一半,那么您可以放弃将新矢量(或直接动态阵列,如果矢量无法执行此操作)添加到旧版本的未使用端部。不确定vector是否在该内存区域存储信息,因此这将是非常hacky和可怕的。但这是一个想法。

现在我考虑一下,一个memMove()类型的操作,你将原始中使用的最后一个索引的反向信息复制到原始文件中未使用区域的后面将保留数据。如果您将其设置为数组的新位置,则可以将其指向原始内存区域中间新数据所在的位置。就地移动本身。