8

I would like to 'shrink-to-fit' an std::vector, to reduce its capacity to its exact size, so that additional memory is freed. The standard trick seems to be the one described here:

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

The whole point of shrink-to-fit is to save memory, but doesn't this method first create a deep copy and then swaps the instances? So at some point -- when the copy is constructed -- the memory usage is doubled?

If that is the case, is there a more memory-friendly method of shrink-to-fit? (In my case the vector is really big and I cannot afford to have both the original plus a copy of it in memory at any time.)

4

2 回答 2

3

Well, if you wanted to resize an array, what would you do? You have to create a new one and copy all of the values over - be it individually or with memcpy or whatever. You can't really resize an array in C or C++.

std::vector is pretty much guaranteed to be implemented using an array for its storage (IIRC, the standard does not guarantee that it's an array, but an array is the only thing which can fulfill the various requirements of the API such as how efficient each operation must be; so, in effect, it's guaranteed even if that guarantee isn't explicit). As it's implemented using an array, and you can't resize arrays without copying, you can't resize vectors without copying.

You could, in theory, have a shrink_capacity() function which hid the fact that you had to temporarily more or less double its size requirements, but since std::vector does not currently have such a function, you have to actually make an explicit copy. The swap trick is just a nice way to do that.

If you really care about memory in such a case, what you can do is use pointers (or smart pointers) instead of having the vector hold the objects directly. That may not be entirely desirable, but it would reduce your memory requirements.

于 2010-04-23T01:15:01.277 回答
-1

如果您的新尺寸是原始尺寸的一半,您可能可以将新矢量(或者如果矢量无法做到这一点,则直接动态数组)放置到旧矢量的未使用端部分中。不确定向量是否将信息存储在该内存区域中,因此这将非常骇人听闻。但这是一个想法。

现在我想起来了,一个 memMove() 类型的操作,您将信息从原始中使用的最后一个索引反向复制到原始中未使用区域的后面,将保留数据。如果您将此作为数组的新位置,您可以将其指向新数据将存在于原始内存区域中间的任何位置。就地移动本身。

于 2010-04-23T01:21:20.903 回答