Reputation: 369
I am simply trying to concatenate a vector to itself but the following code is not working and I am not able to find the issue. If my input vector is {1,2,1}, the o/p I am getting is {1,2,1,1,16842944,1}. Please tell where I am wrong. The output I want is [1,2,1,1,2,1]
vector<int> getConcatenation(vector<int>& nums) {
int size=nums.size();
auto itr=nums.begin();
while(size--)
{
nums.push_back(*itr);
itr++;
}
return nums;
}
Upvotes: 0
Views: 162
Reputation: 76245
The problem, as has been thoroughly pointed out, is that the vector reallocates its storage while the modifications are being done. There are at least three general approaches to this.
First, use an index instead of an iterator:
vector<int> getConcatenation(vector<int>& nums) {
int size = nums.size();
for (int i = 0; i < size; ++i)
nums.push_back(nums[i]);
return nums;
}
Second, use an iterator but ensure that the vector doesn't have to reallocate:
vector<int> getConcatenation(vector<int>& nums) {
int size = nums.size();
nums.reserve(2 * size);
auto itr = nums.begin();
while (--size)
nums.push_back(*itr++);
return nums;
}
(and that approach includes less labor-intensive things like using a builtin algorithm that copies based on iterators)
Third, unless you have to modify the input argument, just build a vector that's the right size and copy into it:
vector<int> getConcatenation(const vector<int>& nums) {
vector<int> result(2 * nums.size());
std::copy(nums.begin(), nums.end(), result.begin());
std::copy(nums.begin(), nums.end(), result.begin() + nums.size());
return result;
}
Upvotes: 1
Reputation: 1
In your original program push_back
invalidates the iterators and using those invalidated iterators can lead to undefined behavior.
One way to solve this would be to use std::copy_n
with std::vector::resize
as shown below:
vector<int> getConcatenation(vector<int>& nums) {
std::vector<int>::size_type old_Size = nums.size();
nums.resize(2 * old_Size);
std::copy_n(nums.begin(), old_Size, nums.begin() + old_Size);
return nums; //NO NEED for this return since the function took vector by reference and so the change is already reflected on passed vector
}
Also you would need to add #include <algorithm>
for std::copy_n
.
Note that since your function takes the vector
be reference, there is no need to return nums
because the changes you do on nums
is already reflected on the original vector. So you can use void
as the return type of the function and then remove the return statement.
Upvotes: 2