如何以节省内存的方式收缩以适应 std::vector ?

发布于 2024-08-30 03:27:07 字数 521 浏览 4 评论 0原文

我想“缩小以适应”std::vector,将其容量减少到其确切大小,以便释放额外的内存。标准技巧似乎是此处描述的:

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

整个要点Shrink-to-Fit的目的是为了节省内存,但是这个方法不是先创建深拷贝然后交换实例吗?那么在某个时刻——当构造副本时——内存使用量会增加一倍?

如果是这样的话,是否有更内存友好的收缩方法? (就我而言,向量非常大,我无法随时将原始向量及其副本保存在内存中。)

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瞎闹 2024-09-06 03:27:07

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

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

理论上,您可以有一个 shr​​ink_capacity() 函数,该函数隐藏了您必须暂时将其大小要求或多或少加倍的事实,但由于 std::vector 确实目前没有这样的功能,您必须实际进行显式复制。交换技巧就是一个很好的方法。

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

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.

掌心的温暖 2024-09-06 03:27:07

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

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

If your new size is half of the original, you might be able to get away with placement newing your new vector (or a straight dynaimc array if vector can't do this) into the unused end portion of your old one. Not sure if vector stores info in that area of memory so this would be very hacky and scary. But it's an idea.

Now that I think about it, a memMove() type operation where you copy the information in reverse from the last index used in the original to the back of the unused area in the original would preserve the data. If you made this a placement new of an array you could point it to wherever the new data would have existed in the middle on the original memory area. An in place move per se.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文