【问题标题】:Is a std::vector more likely to fail than a std::list (STL containers)std::vector 是否比 std::list 更容易失败(STL 容器)
【发布时间】:2013-03-24 05:30:26
【问题描述】:

我了解向量和列表之间关于它们的常见操作复杂性的区别。但是假设我们需要处理非常大的列表或向量(即数百万个元素),我们是否可以说在使用向量时内存分配更有可能失败?

AFAIK,当使用向量时,元素是连续存储的。这意味着需要分配一大块内存来存储所有元素,这在碎片堆的情况下似乎更有可能失败。

另一方面,使用列表时不会分配大块内存;元素不是连续存储的。

【问题讨论】:

  • “似乎”是一个神奇的词。多亏了现代(即 1990 年代后)计算机的虚拟内存架构,“几百万个元素”实际上不存在获取内存的问题。
  • 我认为你已经找到了不同之处。
  • 列表通常会为每个数据项添加两个指针,因此总体内存使用率高于向量。
  • 阅读std::deque。它像list 一样不连续,使用更少的内存并允许随机访问。
  • 这完全取决于您所说的 fail 是什么意思。 std::vector 需要连续的内存(虚拟内存地址),但对于简单类型的内存比std::list 少得多。使用std::list<int> 比使用std::vector<int> 更有可能耗尽内存

标签: c++ stl


【解决方案1】:

比较是不完整的,没有提到两个容器对每个元素的内存要求不同:

  • 平均而言,大小为 N 的向量需要 N*sizeof(T) 字节(您可能需要修剪内存以将大小精确到 N
  • 大小为N 的列表需要N*(sizeof(T)+2*sizeof(void*)) 字节。

由于列表的每个元素都带有两个额外的指针,因此非常小的对象列表(例如,ints)可能需要相同大小的向量所需内存量的三到五倍。随着列表元素大小的增加,额外的内存需求变得不那么明显,但对于小对象,影响是巨大的。这就是为什么说向量更有可能在内存分配上失败是不公平的:虽然向量需要一个连续的内存块,但总量可能要小得多,让您在进入之前拥有更大尺寸的向量潜在失败的领域。

对于大小比两个指针大很多(比如十倍或更多)的对象,您可以放心地忽略额外的内存需求:由于需要向量来分配连续空间,因此可能找不到合适的内存块明显更高。

【讨论】:

  • 我们可以忽略这两个指针。我没有提到它,但我正在考虑大对象列表,而不是简单的整数。
【解决方案2】:

在某些情况下,std::liststd::vector 更有可能继续工作。最直接的一种是当应用程序具有大量内存碎片时。本质上,当分配分布在虚拟内存地址空间中时。这导致可用内存量与最大的连续内存块之间存在很大差距。在这种情况下,具有大量元素的 std::vector 比具有相同数量元素的 std::list 更有可能失败。

但是,我不会盲目地以此为基础做出决定。如果有问题的应用程序出现内存碎片并且影响了我使用std::vector 的能力,那么我会考虑跳转到std::list。但一开始我会选择我认为最适合我需要的任何系列。

【讨论】:

  • 我觉得这个分析有点简单……对于简单/小类型,std::list 的开销比std::vector 的开销要大得多,所以你也可以声称你远不止于此std::list 可能会耗尽内存而不是 std::vector 如果你估计和reserve 预先估计一个近似数字......这里有很多未知数可以在任何一个方向上做出声明。
  • @DavidRodríguez-dribeas 是的,肯定还有其他情况需要考虑。我的意图是勾勒出一个具体的场景,其中一个集合比另一个集合更容易失败。存在许多其他情况,可能会以一种或另一种方式影响您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
相关资源
最近更新 更多