所以我一直在寻找动态数组的实际工作方式。我发现的是两个不同的概念。
在C ++中
在C ++中,动态数组通常由向量实现。向量将容量设置为0,增加计数以插入新元素,然后将新插入的容量大小加倍。
vector.h
/*
* Implementation notes: Vector constructor and destructor
* -------------------------------------------------------
* The constructor allocates storage for the dynamic array and initializes
* the other fields of the object. The destructor frees the memory used
* for the array.
*/
template <typename ValueType>
Vector<ValueType>::Vector() {
count = capacity = 0;
elements = NULL;
}
用于扩展矢量大小
/*
* Implementation notes: expandCapacity
* ------------------------------------
* This function doubles the array capacity, copies the old elements into
* the new array, and then frees the old one.
*/
template <typename ValueType>
void Vector<ValueType>::expandCapacity() {
capacity = max(1, capacity * 2);
ValueType *array = new ValueType[capacity];
for (int i = 0; i < count; i++) {
array[i] = elements[i];
}
if (elements != NULL) delete[] elements;
elements = array;
}
在Java中
在java中,动态数组是使用arrayList实现的,它们将容量设置为10(基于JVM),一旦容量满,它们就会增加容量。 将容量设置为10的原因是您不必为每次新插入频繁初始化内存。一旦容量完全增加容量大小。
好奇心
为什么在vector.h中实现将默认值设置为0?将容量设置为某个较小的值(比方说10)而不是将其设置为0可以节省每次用户插入元素时初始化内存的开销。
由于它是一个动态数组,因此设置较小的矢量容量不会有害,因为动态数组的大小一般超过10个。
编辑:我的问题是为什么默认为0?默认情况下,它可以是任何小值,因为无论如何,矢量将扩展到某个特定大小,这是首先使用矢量的目的。
答案 0 :(得分:6)
默认情况下,容量为零的优势在于默认构建std::vector
根本不会进行任何动态内存分配(你不会为你所做的事付出代价)需要)。
如果您知道需要~10个元素,则可以通过调用std::vector::reserve
明确设置容量:
std::vector<int> vec;
vec.reserve(10);
我只能推测,为什么Java做的事情有所不同,但afaik,动态内存分配在Java中比在c ++中更便宜,而且这两种语言在性能/低级控制与简单性方面也遵循不同的理念。 p>
答案 1 :(得分:3)
为什么默认为0?
实际上它默认不是0。也就是the C++ language standard does not define (AFAIK) what the initial capacity of a default-constructed vector should be。
在实践中,大多数/所有实现都默认为0容量。我想说的原因在于C ++语言的一个设计原则是:
你不使用什么,你不付钱。
(见:B. Stroustrup:The Design and Evolution of C++。Addison Wesley,ISBN 0 - 201 - 43330 - 3,1994年3月)
这不仅仅是一个微不足道的重言式 - 它是设计考虑的倾向。
因此,在C ++中,我们宁愿不为没有插入任何元素的向量支付任何,然后通过初始“牺牲”来节省潜在的大小增加。
正如@yurikilocheck指出的那样,std::vector
类确实为您提供了reserve()
方法,因此您可以自己设置初始容量 - 并且由于默认构造函数不分配任何内容,你不会为两次分配支付“额外费用” - 只需一次。再次,您(基本上)支付最低可能的费用。
编辑:另一方面,std::vector
在分配更多空间时会部分地突破这一原则,而不是在达到其容量时实际需要的空间。但至少这不是一个多余的分配电话。
答案 2 :(得分:3)
我使用了一个实现,它为每个向量保留了32个元素的默认值。它是原生的Sun C ++ STL实现。那是一场灾难。我有一个完全合理的程序,它的性质必须有几十万这些载体。它的内存不足。它应该运行得很好,因为在那些成千上万的元素中,只有很小的百分比使这些向量非空。
因此,根据个人经验,0是最佳默认矢量大小。