【问题标题】:c++ vector avoid reallocation by using .push_back or .resize()c++ 向量通过使用 .push_back 或 .resize() 避免重新分配
【发布时间】:2013-04-05 14:53:49
【问题描述】:

我有一个与矢量有关的问题,尤其是选项 .push_back() 和 .resize()。 使用此选项时,当当前向量容量超出时,c++(STL) 将始终重新分配每个元素。这对我来说是个问题,因为我确实有一个结构对象向量。

std::vector<node> v;

我的结构看起来像这样,并保持指向向量其他元素的指针

struct node
{
    std::array<node*, nrOfNeigh> neighb;
    node* parentNode; 
    double density;
    ...
}

因为我的结构确实有指向向量其他元素的指针,所以在使用 .push_back() 时,这种依赖关系将不再有效。

你们中有人有避免这种情况的想法吗?

我不希望有办法强制 std::vector 不重新分配。 我已经尝试使用 .reserve() 并因此尽可能多地保留。这是可能的,但从内存管理的角度来看并不好。

【问题讨论】:

  • 一定要用std::vector吗?
  • 好吧,当你调用push_back并且没有剩余容量时,它还应该做什么?
  • 您可以通过reserve()函数为您的向量保留最大位置。您可以提供向量的最大容量
  • 为什么需要一个指向数组元素的指针?为什么不只维护 index
  • @Sambo 您还没有回答“为什么需要指针而不是索引”的问题。如果使用索引,则可以在需要时获取指针,即使重新分配向量,索引也永远不会出错。这似乎是您问题的明显答案。

标签: c++ performance memory-management stl


【解决方案1】:

假设结构中的 node* 字段仅指向向量中的其他“节点”对象,您可以将 node* 替换为向量中的整数索引。

具体来说,

struct node
{
    std::array<size_t, nrOfNeigh> neighb;
    size_t parentNodeId;
    double density;
    ...
}

现在,当您使用 push_back() 时,不是存储 &v.back(),而是存储 'v.size()-1'。

【讨论】:

    【解决方案2】:

    我个人会使用 std::vector&lt;node *&gt;(或 Boost 中无数智能指针实现中的任何一个),因此您只需重新分配指向节点的指针,而不是节点本身。

    如果你要走非智能指针路线,不要忘记释放指针。

    编辑:特别是如果你在你的结构中保存整个数组。您不想在每个重新分配周期都重新分配每个固定数组。我也不会使用固定数组,一个内部的std::vector&lt;node *&gt; 来保存邻居会更好地扩展并避免这些天软件似乎困扰的大多数缓冲区溢出问题。

    【讨论】:

    • 我也试过这个,但这意味着我必须动态分配每个元素(最多 20.000.000 或更多),这很慢
    • 我不同意你的评价。
    【解决方案3】:

    好吧,您可以使用vector.reserve() 功能来分配您认为可能需要的尽可能多的内存在使用向量之前,从而可能避免重新分配。在某些情况下,它还可以加速向量推送。见here.

    【讨论】:

    • 我试过这个。手动定义最大数量工作正常。我可以定义大约 2.000.000,但是当使用 .max_size() 成员函数时,我实际上应该能够定义 6.945.456 个元素。
    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 2014-10-25
    • 2021-10-23
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多