简体   繁体   English

递归函数中的分段错误,将结果存储在向量中

[英]Segmentation fault in recursive function, storing result in a vector

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. 显然,我需要添加更多单词,因为我的问题主要是代码。

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. 此外,您还需要在else案例中返回向量。

Moreover, pass v by reference too, in order for the iterator to be OK when yuo check for v.end() . 而且,也通过引用传递v ,以便当yuo检查v.end()时迭代器可以。 Otherwise it will look in a different copy of v at every function call. 否则,它会在每次函数调用时查看v的不同副本。

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);
    }
}

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. 由于您按值传递第一个参数( std::vector ),因此每次调用map都使用与原始不同的向量。 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. 要解决此问题,请通过引用传递std::vector ,而不是按值传递。 Since you are also not changing the vector within the function, pass by const reference: 由于您也没有更改函数中的vector ,因此传递const引用:

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. 第二个问题是您没有从map函数返回值。 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: 要解决此问题,请删除else语句(以避免任何编译器警告)并从函数中返回值:

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);
}

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. 理想情况下,您不会按值传递向量,但这不会导致程序崩溃,只是运行得更慢。

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). 更重要的是,测试i == v.end()也会有未定义的行为(另一个可能的崩溃原因),因为iv.end()不是从同一个容器中获取的迭代器( i是来自向量的迭代器)在main()v是该向量的副本 - 它有一组完全不同的迭代器)。

Lastly, std::map is a templated type in the standard library. 最后, std::map是标准库中的模板化类型。 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. 拥有一个名为map()的函数 - 特别是在using namespace std ,可能会使编程人员感到困惑,如果不会导致编译器模糊不清。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM