如何在 C++ 中动态扩展数组?{像在向量中}

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1350630/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:39:17  来源:igfitidea点击:

How to expand an array dynamically in C++? {like in vector }

c++arraysdynamicexpand

提问by Kim Gr?sman

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?

现在我想向数组添加第 6 个元素。我该怎么做?

回答by Kim Gr?sman

You have to reallocate the array and copy the data:

您必须重新分配数组并复制数据:

int *p;
p = new int[5];
for(int i=0;i<5;i++)
   *(p+i)=i;

// realloc
int* temp = new int[6];
std::copy(p, p + 5, temp); // Suggested by comments from Nick and Bojan
delete [] p;
p = temp;

回答by Crashworks

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.

你不能。为此,您必须使用动态容器,例如 STL 向量。或者,您可以制作另一个更大的数组,然后将第一个数组中的数据复制到其中。

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 imight occupy 0x1014..0x1018. If you then extended the array so that it occupied four more bytes, what would happen?

原因是数组代表内存中的一个连续区域。对于上面的示例,假设 p 指向地址 0x1000,五个整数对应 20 个字节,因此数组在 0x1014 的边界处结束。编译器可以自由地在内存中从 0x1014 开始放置其他变量;例如,int i可能占用 0x1014..0x1018。如果随后扩展数组使其多占用四个字节,会发生什么?

回答by Mehrdad Afshari

If you allocate the initial buffer using mallocyou can use reallocto resize the buffer. You shouldn't use reallocto resize a new-ed buffer.

如果您使用分配初始缓冲区malloc,则可以使用realloc调整缓冲区大小。您不应该使用realloc调整new-ed 缓冲区的大小。

int * array = (int*)malloc(sizeof(int) * arrayLength);
array = (int*)realloc(array, sizeof(int) * newLength);

However, this is a C-ish way to do things. You should consider using vector.

然而,这是一种 C-ish 做事方式。您应该考虑使用vector.

回答by P Shved

Why don't you look in the sources how vectordoes that? You can see the implementation of this mechanism right in the folder your C++ include files reside!

你为什么不看看来源vector呢?您可以在 C++ 包含文件所在的文件夹中看到此机制的实现!

Here's what it does on gcc 4.3.2:

这是它在 gcc 4.3.2 上的作用:

  1. 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 calls operator new()(not just new!) to allocate this chunk, letting himself thereby not to mess with new[]/delete[]stuff;

  2. Copy the contents of the existing array to the newly allocated one;

  3. Dispose previously aligned chunk with the allocator; the default one uses operator delete().

  1. 使用向量的分配器分配一个新的连续内存块(你记得向量是vector<Type, Allocator = new_allocator>?)。默认分配器调用operator new()(不仅仅是new!)来分配这个块,从而让自己不会弄乱new[]/delete[]东西;

  2. 将现有数组的内容复制到新分配的数组中;

  3. 使用分配器处理先前对齐的块;默认使用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.)

(请注意,如果您要编写自己的向量,您的大小应该增加“M 倍”,而不是“固定数量”。这将使您实现摊销的恒定时间。例如,如果,在每次超出大小限制,您的向量增长两次,每个元素将平均复制一次。)

回答by Glenn

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.

与其他人所说的一样,但如果您经常调整数组大小,一种策略是每次通过将大小加倍来调整数组大小。不断地创造新的和摧毁旧的需要付出代价,所以倍增理论试图通过确保未来元素也有足够的空间来缓解这个问题。