Visual C++で
Expression: map/set iterator not dereferencable
というエラーでハマったことをまとめました。
目次
Expression: map/set iterator not dereferencableというメッセージでハマりました
Visual C++でコーディングしていてテストしていると、たまに以下のメッセージが出てきてしまい、結構はまりました。
頭を整理するためにおさらいしてみます。
Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP110D.dll
File: C:\Program Files (x86)\Microsoft Visual Studio
11.0\VC\include\xtree
Line: 237Expression: map/set iterator not dereferencable
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.(Press Retry to debug the application)
C++のSTL(Standard Template Library)とは
C++のSTLとは、C++からvector、list、set、mapなどのコンテナなどを使えることができる便利なライブラリ群です。
このあたりは、Javaでは標準で装備されています。
その昔、C言語を使っていた頃ではC言語ではコンテナが標準で装備されていないので自分たちで実装しておりました。
私の場合、C言語の後に、少しだけC++を触ってから、Javaを使い始めたので、Javaを使い始めた当時は、なんて便利なんだろうって思いました。
C++のSTLでは、Javaを参照にして実装したのでしょうか?
Javaのコンテナとよく似ています。
mapを使ったサンプルは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include "stdafx.h" #include <map> #include <iostream> #include <string> using namespace std; void main() { map<int, std::string> map1; map<int, std::string>::iterator it; int check1; map1.insert(pair<int, std::string>(3, "aaa")); map1.insert(pair<int, std::string>(5, "bbb")); map1.insert(pair<int, std::string>(1, "ccc")); it = map1.begin(); while(it != map1.end()) { int check1 = (*it).first; std::string string1 = (*it).second; cout << " first=" << check1; cout << " second=" << string1 << endl; it++; } } |
実行してみるとこんな感じになります。
1 2 3 |
first=1 second=ccc first=3 second=aaa first=5 second=bbb |
mapで大事なことの一つに必ず、値の入力順ではなくてキーの順番にソートされることです。
これは、結構重要です。
Expression: map/set iterator not dereferencableの原因
上記のコードですが、以下のように変更してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include "stdafx.h" #include <map> #include <iostream> #include <string> using namespace std; void main() { map<int, std::string> map1; map<int, std::string>::iterator it; int check1; /* map1.insert(pair<int, std::string>(3, "aaa")); map1.insert(pair<int, std::string>(5, "bbb")); map1.insert(pair<int, std::string>(1, "ccc")); */ it = map1.begin(); check1 = (*it).first; while(it != map1.end()) { int check1 = (*it).first; std::string string1 = (*it).second; cout << " first=" << check1; cout << " second=" << string1 << endl; it++; } } |
すると見事に
check1 = (*it).first;
の行で
map/set iterator not dereferencable
というエラーが発生します。
要するにmapは空なのにも関わらず、イテレーターから値を参照しようとするのがマズいです。
このようにしてみると当たり前ですが、実は、呼び出し元からmapに値が入ってこないことがあまり考えられないケースだったのでハマってしまいました。
最後に dereferencable って何?
dereferencableって辞書を引いても載っていないです。
dereferencable は、Common misspelling of dereferenceable って書いてあります。
ミススペル?
さらに、derefenceを調査すると見つかりました。
derefence = 「ポインターから参照先の値を取得する」って載っていました。
Expression: map/set iterator not dereferencable
を訳すと
map/set iteratorのポインターから参照できませんでした。
となるのでしょうか。
IT業界のミススペルについては以下にまとめました。
まとめ
スタンダードテンプレートライブラリはとても便利なのですが、標準のC++本には書いていないものがほとんどです。
プログラミングの無料レッスン体験
約8,000名の受講生と80社以上の導入実績のあるプログラミングやWebデザインのオンラインマンツーマンレッスンCodecamp
<Codecampの特徴>
1 現役エンジニアによる指導
2オンラインでのマンツーマン形式の講義
3大手企業にも導入されている実践的なカリキュラム
↓無料体験レッスン実施中です。
コメント
これ、pair使わなくても大丈夫でした。
map1[3.0f]= “aaa”;
map1[5.0f]= “bbb”;
map1[1.0f]= “ccc”;
map1[6.0f]= “ddd”;
map1[8.0f]= “eee”;
map1[11.0f]= “fff”;
for(auto a :map1) {
cout << " first=" << a.first;
cout << " second=" << a.second << endl;
}
説明不足でした。
float で試したバージョンです。
map map1;
map<float, std::string> map1;
仕方ないので全角文字にしました。<>
ほぉ。なるほどね。
このサンプルだとpairなしで実装できるってことですね。