Reputation: 21
I need to transform an array from {4, 2 ,5}
to {4, 2, 5, 4, 2, 5}
. Here's my output: {4, 2, 5, 3.21143e-322, 0, 2}
, which is obviously incorrect. But I cannot seem to figure out the issue in my logic. Perhaps another perspective can find that issue.
This is my code:
void repeatArray(double* oldArray, int size) {
int newSize = size * 2;
double* newArray = new double[newSize];
for (int i = 0; i < size; i++) {
newArray[i] = oldArray[i];
}
for (int i = 0; i < size; i++) {
newArray[size+i] = oldArray[i];
}
oldArray = newArray;
delete [] newArray;
}
int main() {
double* oldArray = new double[3];
oldArray[0] = 4;
oldArray[1] = 2;
oldArray[2] = 5;
repeatArray(oldArray, 3);
for (int i=0; i<6; i++)
cout << oldArray[i] << endl;
delete []oldArray;
return 0;
}
Upvotes: 1
Views: 16203
Reputation: 5694
Since you said C++
, I suggest you use a proper container, e.g. std::vector
.
If you don't have a very good reason to do your own memory management, than you should avoid using new
and delete
, see here for an elaborated explanation.
Using templates enhances the possibility to reuse the repeat
function with other types than double
.
Thus, your code is reduced to the following and is easier to read.
#include <vector>
#include <iostream>
template <typename T>
std::vector<T> repeat(const std::vector<T>& originalVec) {
auto repeatedVec = originalVec;
repeatedVec.insert(repeatedVec.end(), originalVec.begin(), originalVec.end());
return repeatedVec;
}
int main() {
std::vector<double> oldArray {4,2,5};
const auto newArray = repeat(oldArray);
for (const auto item : newArray) {
std::cout << item << std::endl;
}
return 0;
}
Upvotes: 0
Reputation: 3106
The problem is that repeatArray
parameters are local to the function, so if you change their value, the change won't be seen past the function call. You can use a pointer to pointer double** oldArray
to change what oldArray
is pointing to, or return the pointer of the new array location.
However, this is C++
, where you can use STL containers. Your code would become much more simple and readable.
void repeat( std::vector<double>& numbers ) {
// Reserve rellocates the vector if there is not enough space
// otherwise, the iterators first and last could be invalidated.
numbers.reserve( numbers.size() * 2 );
auto first = numbers.begin();
auto last = numbers.end();
std::copy( first, last, std::back_inserter(numbers) );
}
int main() {
std::vector<double> nums({4, 2, 5});
repeat(nums);
for( double num : nums ) {
std::cout << num << '\n';
}
return 0;
}
std::vector
takes care of your allocation, reallocation and copy of the elements, and the deallocation of the resources it makes use.
Upvotes: 1
Reputation: 2107
The problem is that merely assigning the new array to the pointer in repeatArray()
does not change it from the outside.
What you can do in repeatArray()
is to return the newly created array.
double* repeatArray(double* oldArray, int size) {
int newSize = size * 2;
double* newArray = new double[newSize];
for (int i = 0; i < size; i++) {
newArray[i] = oldArray[i];
}
for (int i = 0; i < size; i++) {
newArray[size+i] = oldArray[i];
}
delete [] oldArray;
return newArray;
}
And in main()
:
oldArray = repeatArray(oldArray, 3);
A probably better approach would be to use std::vector
that is resized automatically as needed.
Upvotes: 6