2016-03-31 8 views
0

この関数は、ベクトル、リンクリスト、およびダブルリンクリストで動作します。関数は値をとり、コンテナ内の値を検索します。 vlaueがコンテナ内にある場合、関数はすでに存在する場所のすぐ隣に値を挿入します。したがって、val=2の場合、{3,2,5}{3,2,2,5}になります。しかし、値がコンテナに存在しない場合は、代わりにバックに追加されます。EXCイテレータのアクセスが悪い

イテレータを使用してこの関数を書きました。それはベクトルでうまく動作しますが、リストまたは二重リンクリストで実行しようとすると、if (*it==val)のExc Bad Accessエラーが発生します。私は何が間違っているのか見ていない。

template <class Container, class T> 
void insertNextTo(Container &x, const T &val){ 
    typename Container::iterator it = x.begin(); 
    while (it!=x.end() && *it!=val){ 
     ++it; 
    } 
    if (*it == val){ 
     x.insert(it, val); 
    } 
    else{ 
     x.push_back(val); 
    } 
} 

編集:みなさんありがとうございます! ifの声明を変更する提案は完全に機能しました!

+0

'val'が見つからない場合、' if'条件はUBにつながる終了要素を導出します。 – Mahesh

答えて

2

変更

if (*it == val) 

if (it != x.end()) 

valがコンテナに見つからない場合、ループはit == x.end()。これは配列の最後を指しているので、それを介して間接的には未定義の動作になります。

0

私が間違っていれば誰かが私を修正しますが、あなたのエラーは、イテレータがリストの最後に到達したときに実際にはメモリ内のリストの最後のビットの後のアドレスを指しているスコープが初期化されていてもいなくてもかまいません。

2

値がまだ存在しない場合は、ループが終了したときにitend()に等しくなり、end()を参照できなくなります。唯一のループに到達した場合、あなたは一つの値だけを挿入しているので、あなたがvalを見つけた場合、あなたがinsert()を行うことができますし、すぐに機能を終了し、

また
//if (*it == val){ 
if (it != x.end()){ 
    x.insert(it, val); 
} 

、その後、push_back():あなたは代わりにif (it != x.end())if (*it == val)を変更する必要があります容器の端:その場合、あなたは代わりに手動ループのstd::find()を使用して、コードを簡素化することができ

template <class Container, class T> 
void insertNextTo(Container &x, const T &val) { 
    typename Container::iterator it = x.begin(); 
    while (it != x.end()) { 
     if (*it == val) { 
      x.insert(it, val); 
      return; 
     } 
     ++it; 
    } 
    x.push_back(val); 
} 

#include <algorithm> 

template <class Container, class T> 
void insertNextTo(Container &x, const T &val) { 
    typename Container::iterator it = std::find(x.begin(), x.end(), val); 
    if (it != x.end()) { 
     x.insert(it, val); 
    } else { 
     x.push_back(val); 
    } 
} 

あるいはこれ、それはend()イテレータを使用してinsert()に安全であることから、それが効果的push_back()と同じです:

template <class Container, class T> 
void insertNextTo(Container &x, const T &val) { 
    typename Container::iterator it = std::find(x.begin(), x.end(), val); 
    x.insert(it, val); 
}