How to expand an array dynamically in C++? {like in vector }
Solution 1
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;
Solution 2
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?
Solution 3
If you allocate the initial buffer using malloc
you can use realloc
to resize the buffer. You shouldn't use realloc
to resize a new
-ed buffer.
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
.
Solution 4
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.)
Solution 5
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.
Jesse Beder
Googler, mathematician. Check out Optia, a puzzle game for iOS, or yaml-cpp, a YAML parser/emitter library in C++.
Updated on December 09, 2020Comments
-
Jesse Beder over 3 years
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?
-
Jesse Beder almost 15 yearsIf you indent four spaces in the editor, your code will look like code
-
sbi almost 15 yearsYou don't. If you want this kind of functionality, you'd use
std::vector
. If you don't usestd::vector
, you ought to know quite a lot about C++ (since you ask this, you probably don't have enough yet) and you should have a very good reason. Depending on that reason, the answer might differ.
-
-
Kiran Kumar almost 15 yearsthat is basically reimplementing vector, isn't it?
-
Nick Dandoulakis almost 15 yearsthis is fine for 'int' type but for user defined types,
memcpy/delete []
approach can cause problems. -
Bojan Resnik almost 15 yearsYou can use std::copy instead of memcpy - it will work for PODs as well as objects with user-defined assignment operator and it is likely that it is optimized to memcpy for integral types. The optimization, however, is a quality-of-implementation issue.
-
Kim Gräsman almost 15 yearsThanks guys, I changed to std::copy.
-
peterchen almost 15 yearsWorks only for Plain Old Data types.
-
josesuero almost 15 yearsYou should probably add that what vector does, if he wants to emulate that, is allocate a new, bigger array, and copy the elements to that. The OP is aware of vector, so presumably there's a reason for not using it (homework, perhaps)
-
Glenn almost 15 yearsif you don't want the vector, this is what you might do. But then, if you implement vector, you don't ask this question.
-
Kim Gräsman over 11 yearsThis was fixed thanks to a rejected edit by anonymous user. Thanks for finding that bug! It snuck in when I changed from memcpy to std::copy without checking order of arguments. stackoverflow.com/review/suggested-edits/1775715 <-- this should have been accepted!
-
Jeremy Trifilo over 5 yearsCan you please explain the problems associated with memcpy. Is it just safety checks for length and memory access or are there actual underlying problems with memcpy?
-
Kim Gräsman over 5 years@JeremyTrifilo The issue was raised for user-defined types. If you have an array of objects with user-defined assignment operators (e.g. they need to free/allocate private memory),
memcpy
will break as it just blits the bytes rather than invoking assignment for every element.