3

我一直在玩动态数组结构,并且我注意到 g++ 标准库的向量实现通过在当前容量被填满后调用的每个 push_back() 上将 std::vector 的容量增加一倍。我认为有人提到微软编译器使用 1.5 作为乘数是在 stackoverflow 上的某个地方。我很好奇,这些值是硬编码的还是我可以在某处设置自定义乘数?

4

3 回答 3

1

我相当确定这是一个“实施细节,不需要披露”,我希望它也不必是一个常数,它可能是这样的:

std::vector::grow()
{
    if (size <= 100)
    {
       newsize = size * 2;
    }
    else if (size <= 10000)
    {
       newsize = size * 3 / 2;  /* 1.5x */
    }
    else
    {
       newsize = size * 5 / 4;  /* 1.2x */
    }
    .... allocate a "newsize" chunk of memory etc ... 
}

据我所知,没有“设置乘数”的界面。由每个实现来选择增长率。当数字变得非常大时,2x 有点浪费,并且您冒着“用完虚拟空间”的风险(例如,在 的向量中使用 512M 元素超过 2GB 的限制int,这可能无法作为 32 中的单个分配工作位系统)。

于 2013-04-15T22:57:26.010 回答
1

该标准不要求为您提供一种自定义乘数的方法,尽管您当然可以编写自己的集合或覆盖一个集合并使用它做任何您想做的事情。这是微软的实现,来自 VS 2012:

void _Reserve(size_type _Count)
    {   // ensure room for _Count new elements, grow exponentially
    size_type _Size = size();
    if (max_size() - _Count < _Size)
        _Xlen();
    else if ((_Size += _Count) <= capacity())
        ;
    else
        reserve(_Grow_to(_Size));
    }

您可以看到它们总是以size()--从而使容量增加一倍而增长,并且它不是您(作为程序员)打算覆盖的值。

于 2013-04-15T23:04:43.607 回答
1

我可以在某处设置自定义乘数吗?

其他答案已经直接处理了这个(以及你的问题的其余部分),所以我不会费心重复任何一个。但是,如果您想控制vector自己的增长,请使用std::vector::reserve. 如果您在将元素插入到已满的任何时候调用它vector,那么您可以获得相同的结果(尽管需要一些额外的开销,因为您需要一个冗余条件来检查大小)。

于 2013-04-15T23:51:10.703 回答