2013-04-15 22 views
3

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

+0

查看相关问题http://stackoverflow.com/questions/7774938/in-c-will-the-vector-function-push-back-increase-the-size-of-an-empty-array – user1929959

+0

或其他相关问题:http://stackoverflow.com/questions/5232198/about-vectors-growth – scones

+0

从查看libstdC++源代码,决定增加容量的代码似乎是1239行的函数'_M_check_len' [here ](http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01069_source.html#l)。它以当前大小加上当前大小的最大值或传入的最小值(达到某个最大大小值)返回新容量。 –

回答

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会更浪费一点,而且你有可能会“虚拟空间不足”(例如,在一个向量为int的矢量中使用512M元素超过了2GB的限制,这可能不会在单个分配中起作用32位系统)。

+0

我很肯定他在问实际的实施细节...... –

+0

而且这确实是每个实施都会“以任何方式幻想”的事情。 –

+0

感谢您的回答。似乎g ++似乎保持在2,可能是由Kerrek SB提到的原因。 (无论如何,你需要一个512M数组的整数来穿越2GiB的障碍(不能修复它,因为Stackoverflow不允许单字母编辑 - 在工程论坛上一个愚蠢的政策,如果你问我))。 – PSkocik

1

该标准并不要求您提供一种自定义乘数的方法,当然您可以编写自己的集合或重写一个,并根据需要做任何事情。下面是微软的实施,从2012 VS:

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()增长--thus加倍的能力,这不是一个值,你(作为程序员)旨在覆盖。

+0

您需要查看'_Grow_to'来确定发生了什么。在它被调用的地方,'_Size'是所需的最小值,而不是新的大小。 –

+0

@PeteBecker你说得对,我错过了。我会挖掘并更新我的答案。 –

1

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

其他答案已经在直接意义上处理了这个(和你的问题的其余部分),所以我不打算重复这些。但是,如果您想自己控制vector的增长,请使用std::vector::reserve。如果您在任何时候将此元素插入到已满的vector中,则可以调用该元素,那么您可以获得相同的结果(虽然稍微有些额外开销,因为您需要冗余条件来检查大小)。

相关问题