2017-09-10 12 views
1

このsegフォルトが発生し続けるが、どこから来たのか分からない。 申し訳ありません。私はまだコーディングを始めていません。ベクトルの結果を格納する再帰関数のセグメンテーションフォルト

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

明らかに、私の質問は主にコードなので、もっと言葉を追加する必要があります。

+0

どの回線で障害が発生していますか? –

+2

値ではなく、参照によってベクトルを渡します。 – PaulMcKenzie

答えて

2

ベクトルを値で渡すと、変更は関数呼び出し間で維持されません。

これを達成するには、参照によってベクターを渡します。

さらに、elseケースでもベクターを返す必要があります。

また、v.end()を確認するときにイテレータが正常になるように、参照によってvを渡してください。それ以外の場合は、すべての関数呼び出しで別のコピーvが検索されます。一緒にすべてを置く

は、あなたが得る:

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

@xaxxonが更新されました、どう思いますか?ああ、私もあなたが答えを投稿したことを確認し、しばらくそれをチェックします(私はそれが好きなら私のupvoteが表示されます)。 – gsamaras

0

あなたは多くの状況で、あなたの再帰関数から値を返すていないため、問題がほぼ確実である:

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 **/ 
    } 
} 

代わりに、作ります最後の行は:

return map(v,i,result); 

理想的には値渡しではなくベクトルで渡すあなたのプログラムがクラッシュすることはなく、遅く実行されます。

1

二つの問題があります。

あなたは値によって最初のパラメータ(std::vector)を通過しているので、mapへの各呼び出しは、オリジナルとは異なるベクトルを使用しているが。したがって、渡しているイテレータは渡されたベクトルと互換性がなく、プログラムは未定義の動作を示します。

この問題を解決するには、値ではなくstd::vectorを参照渡しします。あなたもconst参照渡し、関数内vectorを変更していないので:

vector<int> map(const vector<int>& v, vector<int>::iterator i, vector<int> result) 

今イテレータは、渡された実際のベクトルではなく、ベクトルの一時的なコピーを反復されます。

2番目の問題は、map関数から値を返さないことです。値を返すと思われる関数から値を返さないことは、未定義の動作です。

、問題を修正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); 
} 
0

一つの潜在的な原因は次のようになりますreturn文の一部(またはその一部)。呼び出し元が戻り値にアクセスすると、結果は未定義の動作になります。

それを無視しても、引数は値渡しです。したがって、ベクトルに加えられた変更は呼び出し元には表示されません。より具体的には、iv.end()は同じコンテナから取得されたイテレータではないため、i == v.end()のテストでは未定義の動作(クラッシュの別の潜在的な原因)もあります。iは、main()のベクトルからのイテレータであり、vは、これは全く異なるイテレータのセットを持っています)。

最後に、std::mapは、標準ライブラリのテンプレート型です。 map()という名前のファンクション(特にusing namespace stdが有効な場合)は、プログラマを混乱させる可能性があります。コンパイラがあいまいにならないようにしてください。

関連する問題