Direct comparison
| std::vector | C memory functions
------------------------+------------------+------------------------
default capacity | undefined | undefined
default grow | towards capacity | undefined
deterministic capacity | available | no
deterministic grow | available | no
deterministic mem.-move | available | no
non-POD types | yes | f***ing no (*)
no-throw | no | yes
deterministic mem.-move
是从deterministic capacity/grow
推导出来的。当realloc
和std::vector
不得不将其存储的元素移动到新的内存位置时,就会发生这种情况。
我认为,在考虑任何类型的移动(智能)引用时,内存移动方面的(可用的)确定性是双重重要的。
注意:在这方面,我使用“确定性”一词与我的源代码生命周期相关,即其跨不同版本的不同库以及具有不同编译标志等的生命周期。
源
它像realloc
一样会使内存碎片化:
类模板vector概述[vector.overview]
向量的元素被连续存储,这意味着如果v
是一个vector<T,Allocator>
,其中T
是除bool
之外的某种类型,则对于所有0<= n < v.size()
,都遵循恒等式&v[n] == &v[0] + n
换句话说,所使用的内存是连续的。
它与realloc
的一个重大区别是,realloc
实际上可以在没有明确指示的情况下增加已分配的内存部分,但不需要这样做(man 3 realloc
):
man 3 realloc
realloc()
函数将指针ptr
所指向的内存块的大小更改为size
字节。范围从该区域开始到旧大小和新大小的最小值的范围内的内容将保持不变。如果新大小大于旧大小,则添加的内存将不会初始化。如果ptr
为空,则对于所有大小值,调用等效于malloc(size)
;如果size
等于零,并且ptr
不为空,则调用等效于free(ptr)
。除非ptr
为空,否则它必须由先前的malloc()
、calloc()
或realloc()
调用返回。如果指向的区域被移动,则执行free(ptr)
。
因此,它可以增加大小,但不一定要这样做。
std::vector
不仅携带size
,还携带capacity
。如果您预先知道需要一个大的vector
,但是现在无法初始化所有内容,则可以像这样增加向量的容量:
std::vector<T> vec(32);
vec.reserve(1024);
// vec has size 32, but reserved a memory region of 1024 elements
因此,与
realloc
不同的是,使用
std::vector
可以确定重新分配发生的时机。
回答您的问题:因为有了
std::vector
,所以不需要使用
realloc
。而且,对于非POD类型,不允许使用
malloc
、
free
和
realloc
函数;对非POD类型直接使用这些函数会导致未定义的行为。
realloc
有能力扩展现有块,这肯定比那好得多吧? - Ben Hymers