1

I'm trying to return a vector from a function. My code compiles and I've checked my function and reckon that the error comes from the return part. It compiles fine (using Cygwin) but when running it, I get an Aborted (core dumped) error. Here is my code:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

//function that returns the square
int f(int n)
{
    return n*n;
}
vector<int> myVec;
int counter = 0;
//function that uses f on all elements in a list
vector<int> map(vector<int> something)
{
    //base case
    if(counter == something.size())
    {
        /*cout << "hello" << endl;
        for (int i=0; i<counter; i++)
        {
            cout << "vector: " << myVec[i] << endl;
        }*/
        counter=0;
        return myVec;
    }
    //recursion
    else
    {
        //cout << "counter: " << counter << endl;
        int n = f(something[counter]);
        //cout << "n: " << n << endl;
        myVec.push_back(n);
        //cout << "vector: " << myVec[counter] << endl;
        counter++;
        map(something);
    }
}

int main()
{
    //making vectors
    vector<int> L;
    vector<int> L1;
    vector<int> L2;
    for (int i=0; i<20; i++)
    {
        L.push_back(i);
    }
    L1 = map(L);
}

The code was originally from a class file.

5
  • Turn on warnings when you compile your code, then it will tell you that "not all paths return a value". Since returned objects have their destructor called by the compiler, and garbage is returned when you "don't return anything", the destructor is called with garbage as input - which is likely to crash, since a valid vector will contain pointers and such. Commented Apr 3, 2017 at 7:16
  • I used -Wall when compiling and just get a warning about comparison of signed and unsigned integers and a warning about control reaches end of non-void function. Commented Apr 3, 2017 at 7:35
  • Unrelated, but using a global parameters in a recursive call is not a good design unless you document that your function is not thread safe and you encapsulate it in another function that initialize the global variables. Commented Apr 3, 2017 at 7:46
  • Yeah it's because counter was originally in my constructor. Commented Apr 3, 2017 at 7:53
  • Are you using a very old version of gcc then? Both clang and gcc give me a warning - clang without even asking for -Wall. Commented Apr 4, 2017 at 6:41

2 Answers 2

1

In your recursion, you do not return anything. The function is expected to return a Vector.

In your case, what happens if the function enters the "else" case on its first call? It reenters map() until the condition is met, then returns a vector. That vector is passed to the previous recursive call and immediately deleted, as it is not passed any further.

The solution here would be to change the last line of the else-case to

return map(something);

so the value is not lost and correctly passed through to the original caller (your main function).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I totally forgot about returning the function!
1

ALWAYS return a vector when your return type is a vector. In your function, there's a branch that won't return anything, and that will cause problems.

vector<int> map(vector<int>& something)
{
    //base case
    if(counter == something.size())
    {
        /*cout << "hello" << endl;
        for (int i=0; i<counter; i++)
        {
            cout << "vector: " << myVec[i] << endl;
        }*/
        counter=0;
        return myVec;
    }
    //recursion
    else
    {
        //cout << "counter: " << counter << endl;
        int n = f(something[counter]);
        //cout << "n: " << n << endl;
        myVec.push_back(n);
        //cout << "vector: " << myVec[counter] << endl;
        counter++;
        map(something); //you should return a vector here
        return std::vector<int>(); //empty vector
    }
}

Also notice the "&" symbol I added at the function call so that the vector is passed by reference. Otherwise you're passing a copy that won't be changed. I don't know what that "map" function does, so I can't suggest better models to what you're doing.

5 Comments

Ah I see, is there a way to get around returning something in my else statement? I don't want to return anything in my else statement. And my map function uses the f function to return a vector with all it's elements being affected by the f function. It's using recursion to do this.
Well, you can keep it as is, and then check if the vector is empty. Or you can pass another vector by reference that should have the result, and you modify it if you want. There are many, many ways. But keep in mind that C++ is very low level. You deal with memory and the processor directly. If a function is expected to return a vector, it MUST return a vector. I think your compiler warned you about that. Otherwise you'll have undefined behavior.
I see but it kind of defeats the purpose of using recursion if you have to return something in the recursion case.
@Hypofreak Again, you have really many ways to do this. It's all a question of design. Off the top of my head, you could create a struct/class that contains a vector and a flag to whether there's a result. And btw, it doesn't defeat the purpose. You're probably used to scripting languages like Python, where everything is the same object. In low-level programming languages, you have to think differently.
@Hypofreak: "it kind of defeats the purpose of using recursion" ... no. What Zinki's answer does is to invoke the recursion and immediately returns its result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.