iterator not decrementable について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たぬき

iterator not decrementable について

#1

投稿記事 by たぬき » 11年前

DXライブラリなどを利用して,
指定された多角形の座標内にマウスポインタが存在するかを知るための関数を作っています.
デバック開始直後は誤作動なく進むのですが,
いざこの関数を利用しようという操作をすると,

Debug Assertion Failed!
~
Expression: vector iterator not decrementable

とエラーが表示されてしまいます.

ブレークポイントを使って,どこがおかしいのか調べてみると,
vector< vector<int> >::const_iterator it_pre_end = --it_end ;
の部分でエラーが起きていることがわかりました.
しかし,どうしてこの部分でエラーが起きてしまっているのかがわかりません.

このエラーの時に,よくやってしまいがちなミスなどがあれば教えていただきたいです.

コード:

#define _USE_MATH_DEFINES
#include <vector>
#include <algorithm>
#include <math.h>
#include <iterator> 


bool Shop::MousePointer(const vector< vector<int> > Map)
{
	//マウスの座標を取得
	GetMouseInputLog(&Button, &ClickX, &ClickY, TRUE);

	//ボックス内にマウス座標が存在するか
	//多角形の頂点から2つの点を選び,それらと点Pの3つ点からなる角度を足していき,360度,-360度ならボックス内.
	//0度ならボックス外.
	vector< vector<int> >::const_iterator it_v = Map.begin();
	vector< vector<int> >::const_iterator it_end = Map.end();
	vector< vector<int> >::const_iterator it_pre_end = --it_end ;

	double sum = 0;

	while (it_v != it_pre_end){

		vector< vector<int> >::const_iterator map;
		map = it_v;

		sum += Angle((*map)[0], (*map)[1], (*(map+1))[0], (*(map+1))[1], ClickX, ClickY);

		++it_v;
	}

	sum += Angle((*it_pre_end)[0], (*it_pre_end)[1], (*(Map.begin()))[0], (*(Map.begin()))[1], ClickX, ClickY);

	if (358 < sum < 362 || 179< sum < 181){
		return true;
	}
	else{
		return false;
	}


}


//角APB
double Shop::Angle(int xA, int yA, int xB, int yB, int xP, int yP){
	double angle;
	int tmp_xA, tmp_yA, tmp_xB, tmp_yB;
	int cos, sin;

	tmp_xA = xA - xP;//ベクトルOA
	tmp_yA = yA - yP;

	tmp_xB = xB - xP;//ベクトルOB
	tmp_yB = yB - yP;

	cos = tmp_xA * tmp_xB + tmp_yA * tmp_yB;
	sin = tmp_xA * tmp_yB - tmp_yA * tmp_xB;

	angle = atan2(sin, cos);

	return (angle * 180.0) / (M_PI);
}

Shop::Shop(){

	~

	vector<vector<int>> left_box = { { 481, 576 }, { 497, 567 }, { 528, 567 }, { 528, 584 }, { 497, 584 } };
	vector<vector<int>> right_box = { { 550, 567 }, { 578, 567 }, { 528, 576 }, { 578, 584 }, { 550, 584 } };
	vector<vector<int>> buy_box = { { 668, 401 }, { 731, 401 }, { 738, 405 }, { 738, 451 }, { 731, 458 }, { 668, 458 }, { 661, 451 }, { 661, 405 } };
	vector<vector<int>> leave_box = { { 660, 502 }, { 738, 501 }, { 747, 507 }, { 747, 569 }, { 738, 577 }, { 660, 577 }, { 652, 569 }, { 652, 507 } };

}


zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: iterator not decrementable について

#2

投稿記事 by zxc » 11年前

  
Expression: vector iterator not decrementable
この大体の訳は「例外: vector のiteratorはデクリメントできない」というようなものだと思います。

  また、ここの次の文章
If the container is empty, this function returns the same as vector::begin.
のようなことが、今回提示されたようなコードでは起こっているのかもしれません。要は空のvectorのbegin(=空なのでendと指す位置が同じ)が指す位置より前をデクリメントで指そうとしたが、そんなことは出来ないということだと思います。

たぬき

Re: iterator not decrementable について

#3

投稿記事 by たぬき » 11年前

zxcさん,返信ありがとうございます.
zxcさんのアドバイスを受け,空のvectorが関数Shop::MousePointerに
渡されている可能性を考え,その関数中に

if (Map.empty()){ return false; }

を書き加えてみたところ,無事,エラーなく動作しました.

しかし,どのタイミングで空のvectorが渡されたのかがよくわかりません.
以下に,Shop::MousePointerを呼び出す部分の関数のコードを示します.
おかしな点,空のvectorを渡していそうな点があれば教えてください.

また,先ほどは示していませんでしたが,同じ関数名(:MousePointer)でオーバーライドしています.
オーバーライド自体,最近学び,初めて使っているので,合っているかが心配です.
もしかすると,この関数に原因があるかもしれませんので,下の方に合わせてコードを示しておきます.

コード:

void Shop::Update(){
	//各ボックス内にマウス座標が存在するか
	GetMousePoint(&MouseX, &MouseY);
	if (MousePointer(SELECT_BOX_X1, SELECT_BOX_Y1,
		SELECT_BOX_WIDTH, SELECT_BOX_HEIGHT)) {
		if (Page.size() == 1){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM1);//そのアイテムをカートにいれる
			}
		}
		else if (Page.size() == 2){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM7);//そのアイテムをカートにいれる
			}
		}
	}

	else if (MousePointer(SELECT_BOX_X2, SELECT_BOX_Y2,
		SELECT_BOX_WIDTH, SELECT_BOX_HEIGHT)) {
		if (Page.size() == 1){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM2);//そのアイテムをカートにいれる
			}
		}
		else if (Page.size() == 2){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM8);//そのアイテムをカートにいれる
			}
		}
	}

	else if (MousePointer(SELECT_BOX_X3, SELECT_BOX_Y3,
		SELECT_BOX_WIDTH, SELECT_BOX_HEIGHT)) {
		if (Page.size() == 1){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM3);//そのアイテムをカートにいれる
			}
		}
		else if (Page.size() == 2){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM9);//そのアイテムをカートにいれる
			}
		}
	}

	else if (MousePointer(SELECT_BOX_X4, SELECT_BOX_Y4,
		SELECT_BOX_WIDTH, SELECT_BOX_HEIGHT)) {
		if (Page.size() == 1){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM4);//そのアイテムをカートにいれる
			}
		}
		else if (Page.size() == 2){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM10);//そのアイテムをカートにいれる
			}
		}
	}

	else if (MousePointer(SELECT_BOX_X5, SELECT_BOX_Y5,
		SELECT_BOX_WIDTH, SELECT_BOX_HEIGHT)) {
		if (Page.size() == 1){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM5);//そのアイテムをカートにいれる
			}
		}
		else if (Page.size() == 2){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM11);//そのアイテムをカートにいれる
			}
		}
	}

	else if (MousePointer(SELECT_BOX_X6, SELECT_BOX_Y6,
		SELECT_BOX_WIDTH, SELECT_BOX_HEIGHT)) {
		if (Page.size() == 1){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM6);//そのアイテムをカートにいれる
			}
		}
		else if (Page.size() == 2){
			if (Click()){ //クリックされたら
				ContentsInCart.push_back(ITEM12);//そのアイテムをカートにいれる
			}
		}
	}


	else if (MousePointer(left_box)) {
		if (Click()){
			if (Page.size() != MAX_PAGE) Page.pop_back();//現在のページ数が最大ページならめくれない
		}
	}

	else if (MousePointer(right_box)) {
		if (Click()){
			if (Page.size() != MIN_PAGE) Page.push_back(1);//現在のページ数が最小ページ(1ページ)ならめくれない
		}
	}
	//購入ボタン
	else if (MousePointer(buy_box)) {
		if (Click()){
			move(ContentsInCart.begin(), ContentsInCart.end(), back_inserter(Belongings));//カートの中の商品を所持品に加える 
		}
	}
	//店から出る
	else if (MousePointer(leave_box)) {
		if (Click()){
			Tem_LeaveFlag = true;
		}
	}
}

//オーバーロード(のつもり)
bool Shop::MousePointer(int x, int y, int width, int height)
{
	int mouseX, mouseY;

	//マウスの座標を取得
	GetMousePoint(&mouseX, &mouseY);

	//ボックス内にマウス座標が存在するか
	if ((mouseX >= x && mouseX <= x + width) &&
		(mouseY >= y && mouseY <= y + height)) {
		return true;
	}
	return false;
}

sleep

Re: iterator not decrementable について

#4

投稿記事 by sleep » 11年前

おそらく、ですが
メンバ変数で left_box、right_box、buy_box、leave_boxを定義されているのではないでしょうか?

以下のコードだと上記を再度コンストラクタのスコープ内にローカル変数として再定義しています。
この場合、メンバ変数は初期化されず、コンストラクタを抜ける際にローカル変数も解放されてしまいます。

コード:

Shop::Shop(){
 
    ~
 
    vector<vector<int>> left_box = { { 481, 576 }, { 497, 567 }, { 528, 567 }, { 528, 584 }, { 497, 584 } };
    vector<vector<int>> right_box = { { 550, 567 }, { 578, 567 }, { 528, 576 }, { 578, 584 }, { 550, 584 } };
    vector<vector<int>> buy_box = { { 668, 401 }, { 731, 401 }, { 738, 405 }, { 738, 451 }, { 731, 458 }, { 668, 458 }, { 661, 451 }, { 661, 405 } };
    vector<vector<int>> leave_box = { { 660, 502 }, { 738, 501 }, { 747, 507 }, { 747, 569 }, { 738, 577 }, { 660, 577 }, { 652, 569 }, { 652, 507 } };
 
}
vectorは宣言のみだと最初中身が空なので、メンバ変数のvectorが初期化されていないまま呼び出されていると予測します。

あと、コード中にはオーバーロードと書かれていて、定義の仕方もオーバーロードなので
文章中のオーバーライドはオーバーロードの誤りかと思われます。

たぬき

Re: iterator not decrementable について

#5

投稿記事 by たぬき » 11年前

sleepさんのおっしゃる通り,意図するようにメンバ変数が初期化されていませんでした.
以下のように,vector<vector<int>>を外してみたところ,関数MousePointer内で,vectorが空かどうかを調べずとも,うまく動作しました.
おそらく,これで,vectorの初期化が行われたのだと思います.
メンバ変数として宣言していたものを,再び型名つきで初期化(もどき)をしようとすると,別の変数(ローカル変数)として扱われてしまうんですね.知りませんでした..

コード:

Shop::Shop(){
 
    ~
 
    left_box = { { 481, 576 }, { 497, 567 }, { 528, 567 }, { 528, 584 }, { 497, 584 } };
    right_box = { { 550, 567 }, { 578, 567 }, { 528, 576 }, { 578, 584 }, { 550, 584 } };
    buy_box = { { 668, 401 }, { 731, 401 }, { 738, 405 }, { 738, 451 }, { 731, 458 }, { 668, 458 }, { 661, 451 }, { 661, 405 } };
    leave_box = { { 660, 502 }, { 738, 501 }, { 747, 507 }, { 747, 569 }, { 738, 577 }, { 660, 577 }, { 652, 569 }, { 652, 507 } };
 
}
回答していただいた皆さん,本当にありがとうございました.

閉鎖

“C言語何でも質問掲示板” へ戻る