Reputation: 3965
I was thinking of ways to make an array larger quickly in C++ and I came up with this:
// set up arr1
int *arr1 = new int[5];
// add data to arr1
arr1[0] = 1;
arr1[1] = 2;
arr1[2] = 3;
arr1[3] = 4;
arr1[4] = 5;
// set up arr2
int *arr2 = new int[10];
arr2 = arr1; // assign arr1 to arr2
// add more values
arr2[5] = 6;
arr2[6] = 7;
arr2[7] = 8;
arr2[8] = 9;
arr2[9] = 10;
Is this even safe? I worry that this will cause some strange behavior and that arr2 is just an int[5] array and you're now overwriting data that doesn't belong to it.
Upvotes: 2
Views: 1440
Reputation: 33655
NO.
arr2 = arr1;
Does not do what you think it does!
There is already something in the STL for this, it's called vector
.
For the sake of completeness.. :)
arr2
before the assignment held the address if the start of the array of 10 items you allocated. After the assignment, rather than copying the contents the block addressed by arr1
(which I guess is what you wanted to do), the assignment merely changes the address that arr2
holds to the address that arr1
holds (i.e. start of the 5 item array), for the rest of your code, this has two consequences:
arr2
, by the assignment, you're now addressing a block that only has 5 items, and accessing anything outside of that block of 5 (i.e. indexes 5 onwards) is likely to end in nasal daemons paying a visit with a very large cricket bat - or you may get lucky...So what can you do:
std::vector<int>
, one if it's design features is to take this kind of burden away
from you (unless you're interested in implementing another container), if that's the casestd::copy
- or others, such as memcpy
(prefer memmove
- it's a little slower but is well defined for overlapping blocks etc.)Upvotes: 8
Reputation: 1166
Just to add to the other comments which are correct. The reason why you will leak memory is that you have replaced arr2 pointer that pointed to allocated memory for arr2 with arr1 pointer. Now arr1, arr2 point to the same thing, the array of 5 elements. When you try to clean up with delete operator, you can only clean up the 5 element array since the pointer to 10 element array has been overriden.
Upvotes: 2
Reputation: 34625
Is this even safe?
No
arr2 = arr1; // assign arr1 to arr2
arr2
is also pointing to first index element of arr1
. And by doing it, arr2
looses the location where it was earlier pointing to returned by new
. So, there is memory leak.
Use std::vector instead to expand the array.
Upvotes: 2
Reputation: 47428
The line arr2 = arr1;
leaks memory, and all the following arr2[...]=
lines invoke undefined behavior as they access the array of 5 ints outside of its bounds.
To do what you wanted to do, replace arr2 = arr1;
with std::copy(arr1, arr1+5, arr2);
(example program: https://ideone.com/3Rohu)
To do this properly, use std::vector<int>
Upvotes: 6
Reputation: 19971
No, it's not safe at all. When you said arr2=arr1;
you didn't copy any of the data across, you just reassigned a pointer. Now the memory you allocated with int *arr2 = new int[10];
has been leaked, and arr2
points to the original 5-element array, and when you start saying things like arr2[5] = 6;
you are writing beyond the end of that array and all hell may break loose.
Upvotes: 3
Reputation: 23268
It's not safe that's actually a memory leak. You're not doing anything with arr2 you just ended up setting arr2 to the address of r1, remember in c and c++ theres no bounds checking so you're overwriting another stackframe by doing that
Upvotes: 2
Reputation: 76788
This leaks memory, because you are assigning pointers.
int *arr2 = new int[10];
arr2 = arr1; // this does not assign the values
The second assignment makes arr2
point to the array arr1
. You loose the array you have previously allocated, and can never delete it.
To avoid this, use an std::vector
.
Upvotes: 5