2017-01-12 72 views
0

私は以下のコードを用意しています。"Vector Subscript Out of Range" std :: vectorをstd :: mapの値として使用する

std::vector<GLuint> testVector = { 6, 7, 8 }; 
std::map<std::pair<GLfloat, GLfloat>, std::vector<GLuint>> testMap; 
testMap.insert(std::make_pair(std::make_pair(1.0f,1.0f), testVector)); 

std::vector <GLuint> retrievalVector = 
            testMap.find(std::make_pair(1.0f, 1.0f))->second; 

std::cout << "Retrieval Vector: " << retrievalVector[0] << "\t" 
            << retrievalVector[1] << "\t" 
            << retrievalVector[2] << std::endl; 

retrievalVector.push_back(9); 

std::cout << "Retrieval Vector: " << retrievalVector[0] << "\t" 
            << retrievalVector[1] << "\t" 
            << retrievalVector[2] << "\t" 
            << retrievalVector[3] << std::endl; 

testMap.insert(std::make_pair(std::make_pair(1.0f, 1.0f), retrievalVector)); 
retrievalVector = testMap.find(std::make_pair(1.0f, 1.0f))->second; 

std::cout << "Retrieval Vector: " << retrievalVector[0] << "\t" 
            << retrievalVector[1] << "\t" 
            << retrievalVector[2] << "\t" 
            << retrievalVector[3] << std::endl; 

基本的に、座標をキーにしてマップに整数のベクトルを挿入します。私は同じベクトルを取得し、内容がうまく格納されていることを確認します。私はベクトルに別の整数を加え、同じ場所にそれを挿入し直します。もう一度それを取得し、ベクトルの内容(最後のcout)を印刷しようとすると、範囲外のアクセスが発生します。

これがなぜ起こるのか、知識の豊富な人が説明できますか?

+1

浮動小数点数型は非常に気まぐれですが、正確に一致する必要のあるキーには使用しないことをお勧めします。これは 'GLfloat'の代わりに' int'で動作しますか?また、 'retrievalVector'を操作しようと思っているのであれば、コピーではなく参照として宣言したいかもしれません。 – tadman

+0

マップのキーとして浮動小数点数を使用すると、数値解析に非常に注意が払われない限り、将来すべての種類の悲しみが発生します。代わりにスケーリングされた整数を使用できませんか? –

答えて

1

動作はまったく同じです。 According to the documentation

コンテナに、同等のキーを持つ要素がまだ含まれていない場合は、コンテナに要素を挿入します。あなたの戻り値はする必要がありますので

は、あなたはすでに、そこにstd::make_pair(1.0f, 1.0f)を持っている:

が挿入された要素へのイテレータのペア(または挿入を防止要素)と返します挿入が行われたかどうかを示すbool。

あなたはそれがfalseあるべきtestMap.insert(std::make_pair(std::make_pair(1.0f, 1.0f), retrievalVector)).second確認し、その3要素の配列がまだある場合は、あなたが望んでいない四つの要素1は、プログラムがクラッシュしretrievalVector[3]にアクセスしようとする上で、したがって、追加されていました。

ちなみに、C++ 17にはinsert_or_assign()という機能があり、insert()が望むことをする機能を持っています。

1

2番目のinsertは、すでにその位置に値があるため、失敗するという問題があります。値を変更する場合は、testMap[std::make_pair(1.0f, 1.0f)] = retrievalVector;のような操作を行う必要があります。

関連する問題