2017-06-24 18 views
0

私はstd::vector aを別のstd::vector bにコピーしますが、2を開始インデックスとしてコピーするコードがあります。両方のベクトルの長さが4であるため、境界外の書き込みが発生します。このコードで例外をスローするようにしたいと思いますが、どうしたらいいですか?以下のコードは、セグメント化エラーでクラッシュします。std :: transformで範囲外の例外をスローするにはどうすればいいですか?

#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<double> a = {1, 2, 3, 4}; 
    std::vector<double> b(4); 

    try 
    { 
     std::transform(a.begin(), a.begin()+4, b.begin()+2, 
       [](const double d) { return d; }); 
    } 
    catch (std::exception& e) 
    { 
     std::cout << "EXCEPTION: " << e.what() << std::endl; 
     return 1; 
    } 

    return 0; 
} 
+0

あなたの問題とは無関係ですが、ベクトルを別のベクトルにコピーするだけの場合は、 'std :: copy'の代わりに' std :: transform'を使用するのはなぜですか? –

+0

私はラムダ関数の型を変換しているので、usecaseは少し複雑です。私はこの問題に遭遇し、私の問題を示す最も簡単な例を作りました。 – Chiel

答えて

3

std::transform[d_first, d_first+std::distance(first1, last1))が有効であることを前提としています。

しかし、あなたにも出力範囲に「終わり」イテレータを追加する場合は、独自のアルゴリズムを記述することができます。

template <typename InputIt, typename OutputIt, typename UnaryOp> 
OutputIt safe_transform(
    InputIt first1, InputIt last1, 
    OutputIt first2, OutputIt last2, 
    UnaryOp unary_op) 
{ 
    while (first1 != last1) { 
     if (first2 == last2) 
      throw std::domain_error("Reached end of output range"); 
     *first2 = unary_op(*first1); 
     ++first1; 
     ++first2; 
    } 
    return first2; 
} 
3

transformは、ボンネットの下にそのイテレータを逆参照。 operator[]の境界チェックされたバージョンであるat()を呼び出す方法はありません。 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTICを使用してデバッグコンテナを有効にすることができます。ここで、libstdC++は範囲外で反復する場合、プログラムを終了する「安全なイテレータ」を使用します。

関連する問題