Reputation:
I keep getting this seg fault but I have no idea where it came from. Sorry I'm still new to coding.
#include <iostream>
#include <vector>
using namespace std;
vector<int> map(vector<int> v, vector<int>::iterator i, vector<int> result) { //set i = v.begin() in main
if (i==v.end()) {
return result;
} else {
result.push_back((*i)*(*i));
i++;
map(v,i,result);
}
}
int main() {
vector<int> v;
vector<int> result;
for (int i=0;i<20;i++) {
v.push_back(i);
}
vector<int>::iterator it=v.begin();
result=map(v,it,result);
}
And apparently, I need to add more word because my question is mostly code.
Upvotes: 1
Views: 471
Reputation: 73366
You pass the vector by value, thus the changes don't persist among function calls.
Pass the vector by reference to achieve this.
Furthermore, you need to return the vector in the else case too.
Moreover, pass v
by reference too, in order for the iterator to be OK when yuo check for v.end()
. Otherwise it will look in a different copy of v
at every function call.
Putting everything together, you get:
vector<int> map(vector<int>& v, vector<int>::iterator i, vector<int>& result) {
if (i==v.end()) {
return result;
} else {
result.push_back((*i)*(*i));
i++;
return map(v,i,result);
}
}
Upvotes: 2
Reputation: 36597
One potential cause of a crash will be because the recursive call is not followed by (or part of) a return statement. When the caller accesses the return value, the result is undefined behaviour.
Even ignoring that, the arguments are passed by value. Any changes made to the vector will therefore not be visible to the caller. More significantly, the test i == v.end()
will also have undefined behaviour (another potential cause of a crash) because i
and v.end()
are not iterators obtained from the same container (i
is an iterator from the vector in main()
, and v
is a copy of that vector - which has a completely different set of iterators).
Lastly, std::map
is a templated type in the standard library. Having a function named map()
- particularly when a using namespace std
is in play, is likely to confuse programmers, if not result in ambiguity to the compiler.
Upvotes: 0
Reputation: 35440
There are two problems:
Since you are passing the first parameter (std::vector
) by value, each call to map
is using a different vector than the original. Thus the iterator you're passing is not compatible with the passed-in vector and your program will exhibit undefined behavior.
To fix this problem, pass the std::vector
by reference, not by value. Since you are also not changing the vector
within the function, pass by const
reference:
vector<int> map(const vector<int>& v, vector<int>::iterator i, vector<int> result)
Now the iterator is iterating over the actual vector that was passed in, not a temporary copy of the vector.
The second issue is that you are not returning a value from the map
function. Not returning a value from a function that is supposed to return a value is undefined behavior.
To fix the issue, remove the else
statement (to avoid any compiler warnings) and return the value from the function:
vector<int> map(const vector<int>& v, vector<int>::iterator i, vector<int> result)
{
if (i == v.end())
return result;
result.push_back((*i)*(*i));
i++;
return map(v, i, result);
}
Upvotes: 1
Reputation: 19761
The problem is almost certainly because you're not returning a value from your recursive function in many situations:
vector<int> map(vector<int> v, vector<int>::iterator i, vector<int> result) { //set i = v.begin() in main
if (i==v.end()) {
return result;
} else {
result.push_back((*i)*(*i));
i++;
map(v,i,result);
/** NO RETURN VALUE HERE **/
}
}
Instead, make the last line be:
return map(v,i,result);
Ideally you won't pass in vectors by value, but that won't cause your program to crash, just run more slowly.
Upvotes: 0