【问题标题】:Calling vector::reserve() on a vector reference在向量引用上调用 vector::reserve()
【发布时间】:2013-10-15 16:48:34
【问题描述】:

我已经建立了一个解释现象的理论,但我希望有更博学的人来支持我。

在客户端代码中,我有:

vector<bool> candidates;
fillCandidates(candidates);

在被调用者中,我有:

void fillCandidates(vector<bool>& candidates)
{
    // reserve space for two elements
    candidates.reserve(2);
    candidates[0] = true;
    candidates[1] = false;
    // here, candidates.size() == 0
}

当我在函数返回后检查候选者的大小时,它是0!发生了什么?我在 Ubuntu 12.04 64 位上使用在 CMake 脚本中调用的 gcc 4.6.3(但我认为所有这些实际上都无关紧要)。

注意:我提供我的解释作为答案。

编辑:接受的答案和 cmets 在时间上击败了我,所以我的解释不会添加任何东西。

【问题讨论】:

  • FWIW,只有当计数很高并且事先知道时,才执行reserve 更合适。调用 resize 然后覆盖元素的性能通常较差,除了 POD/内置。如果您可以使用 C++11,则在大多数情况下执行 emplace_back 是合适的并且也很高效。
  • @legends2k:您能否指出您关于emplace_back 性能的声明的来源?这很有趣。
  • @legends2k 非常感谢

标签: c++ stl stdvector


【解决方案1】:

你应该调用resize,而不是reserve。

在此处查看差异: Choice between vector::resize() and vector::reserve()

编辑回答下面的cmets:

简短的回答是肯定的,在只保留的向量上调用 operator[] 是错误的,任何事情都可能发生。

长答案看这篇文章http://www.gotw.ca/gotw/074.htm

v.reserve(2); v[0] = 1; v[1] = 2; 以上两行都是完全错误的,但是 它们可能是难以发现的完全错误,因为它们很可能 在您实施标准库之后“工作”。

我建议阅读全文。 在您的情况下,我会使用 push_back 而不是手动调整大小。但是,如果您真的担心,我会对性能进行基准测试。

【讨论】:

  • 感谢您的指点。但是,作为一个附带问题,我是否通过使用 operator[] 来分配值做坏事?
  • 无论如何,我并不是要分配 2 个默认值(使用 resize() 会发生这种情况)。我真的打算在分配值之前保留足够的空间。试图用operator[] 赋值不是我真正的错误吗?由于在我的情况下 size() 返回 0,因此使用 operator[] 会导致未定义的行为。
  • @sturmer:如果您确定不希望您的矢量元素短暂地采用默认值,那么您可以使用push_back 而不是resize() 创建它。不过,在bool 的情况下,它的效率可能会降低(对于两个bools,效率并不重要)。 vector 永远不会包含尚未初始化的元素,这是预期的功能。
猜你喜欢
  • 1970-01-01
  • 2020-09-22
  • 2011-02-16
  • 2013-06-18
  • 2011-11-15
相关资源
最近更新 更多