如何在C++中动态扩展数组? {像向量一样}
可以说,我
int *p;
p = new int[5];
for(int i=0;i<5;i++)
*(p+i)=i;
现在想向数组添加第六个元素。我该怎么做?
Lets say, i have
int *p;
p = new int[5];
for(int i=0;i<5;i++)
*(p+i)=i;
Now I want to add a 6th element to the array. How do I do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您必须重新分配数组并复制数据:
You have to reallocate the array and copy the data:
你不能。为此,您必须使用动态容器,例如 STL 矢量。或者,您可以创建另一个更大的数组,然后将第一个数组中的数据复制到其中。
原因是数组代表内存中的连续区域。对于上面的示例,假设 p 指向地址 0x1000,并且五个 int 对应于 20 个字节,因此数组在 0x1014 的边界处结束。编译器可以自由地将其他变量放置在从 0x1014 开始的内存中;例如,
int i
可能占用 0x1014..0x1018。如果您随后扩展该数组,使其多占用四个字节,会发生什么?You cannot. You must use a dynamic container, such as an STL vector, for this. Or else you can make another array that is larger, and then copy the data from your first array into it.
The reason is that an array represents a contiguous region in memory. For your example above, let us say that p points to address 0x1000, and the the five ints correspond to twenty bytes, so the array ends at the boundary of 0x1014. The compiler is free to place other variables in the memory starting at 0x1014; for example,
int i
might occupy 0x1014..0x1018. If you then extended the array so that it occupied four more bytes, what would happen?如果使用
malloc
分配初始缓冲区,则可以使用realloc
来调整缓冲区大小。您不应该使用realloc
来调整new
-ed缓冲区的大小。然而,这是一种 C 风格的做事方式。您应该考虑使用
向量
。If you allocate the initial buffer using
malloc
you can userealloc
to resize the buffer. You shouldn't userealloc
to resize anew
-ed buffer.However, this is a C-ish way to do things. You should consider using
vector
.正如其他人所说,但如果您经常调整数组大小,一种策略是每次将大小加倍来调整数组大小。不断地创造新的和摧毁旧的是有代价的,所以加倍理论试图通过确保未来的元素也有足够的空间来缓解这个问题。
Same as others are saying, but if you're resizing the array often, one strategy is to resize the array each time by doubling the size. There's an expense to constantly creating new and destroying old, so the doubling theory tries to mitigate this problem by ensuring that there's sufficient room for future elements as well.
你为什么不看看源代码
vector
是如何做到这一点的呢?您可以在 C++ 包含文件所在的文件夹中看到此机制的实现!这是它在 gcc 4.3.2 上的作用:
使用向量的分配器分配一个新的连续内存块(你还记得向量是
vector
吗?)。默认分配器调用operator new()
(不仅仅是new
!)来分配这个块,从而让自己不会弄乱new[]
/delete[]
stuff;将现有数组的内容复制到新分配的数组中;
使用分配器处理先前对齐的块;默认使用
操作符delete()
。(请注意,如果您要编写自己的向量,则您的大小应增加“M 倍”,而不是“固定量”。这将使您实现摊余常数时间。例如,如果每次超出大小限制,你的向量会增长两倍,每个元素平均会被复制一次。)
Why don't you look in the sources how
vector
does that? You can see the implementation of this mechanism right in the folder your C++ include files reside!Here's what it does on gcc 4.3.2:
Allocate a new contiguous chunk of memory with use of the vector's allocator (you remember that vector is
vector<Type, Allocator = new_allocator>
?). The default allocator callsoperator new()
(not justnew
!) to allocate this chunk, letting himself thereby not to mess withnew[]
/delete[]
stuff;Copy the contents of the existing array to the newly allocated one;
Dispose previously aligned chunk with the allocator; the default one uses
operator delete()
.(Note, that if you're going to write your own vector, your size should increase "M times", not "by fixed amount". This will let you achieve amortized constant time. For example, if, upon each excession of the size limit, your vector grows twice, each element will be copied on average once.)