Home > Software engineering >  Code runs correctly but when written as a function it does not
Code runs correctly but when written as a function it does not

Time:08-10

Currently I am trying to fill

std::vector<std::vector<char>> vec

and I'm doing this using this part of code:

std::vector<char> tmp;
for(int b = 0; b < 10; b  ){
    tmp.push_back('#');
}
for(int a = 0; a < 10; a  ){
    vec.push_back(tmp);
}

which works as intended when tested using:

std::cout << vec.size() << "\n";
std::cout << vec[0].size() << "\n";

(the output is: 10 10) The problem comes when i try to make it into a function:

void fill(std::vector<std::vector<char>> v, char ch = 0x20) {
        std::vector<char> tmp;
        for(int b = 0; b < 10; b  ){
            tmp.push_back(ch);
        }
        for(int a = 0; a < 10; a  ){
            v.push_back(tmp);
        }
    }

when tested using:

fill(vec, '#');
std::cout << vec.size() << "\n";
std::cout << vec[0].size() << "\n";

I get a segmentation fault error, which looks like this:

0
Segmentation fault (core dumped)

I suppose the 0 means the vector vec doesn't even get filled with the tmp vectors. I should also say that function fill is a member of a class in a separate file. I can provide it if necessary. I found this but, unfortunately, it wasn't very helpful.

CodePudding user response:

Super common newbie error. When you want a function to calculate something, you should return the result from the function, not pass the result as a parameter.

Like this

std::vector<std::vector<char>> fill(char ch = 0x20) {
    std::vector<std::vector<char>> v;
    ...
    return v;
}

vec = fill('#');

The alternative is to pass a reference to the result to the function

void fill(std::vector<std::vector<char>>& v, char ch = 0x20) {
    ...
}

fill(vec, '#');

Notice the extra & that's what turns v into a reference.

The first is preferable (IMHO) but many newbies prefer the second. I guess because it is closer to the code they tried to write in the first place.

CodePudding user response:

The problem is that vec[0].size() is undefined behavior because you passed the vector by value and so vec is still an empty vector.

To solve this you can pass the vector by reference.

//--------------------------------------v----------------------->pass by reference
void fill(std::vector<std::vector<char>>& v, char ch = 0x20) {
    
}

Note also that you don't need to create and call a function as we can directly initialize the vector as shown below:

std::vector<std::vector<char> > vec(10,std::vector<char>(10, '#'))

Demo

  • Related