プログラミング、ゲームシステムなど普段考えたことについてのメモ帳代わり。
No.9
2010/01/29 (Fri) 07:32:12
卒論のプログラム作成中、エラーが起き、「vector iterators incompatible」というメッセージが表示された。
STLのvectorを利用した際に起こるもので、要素の削除に関連したもの。
前にも何度かやっていて、よく分からずにその当時は投げていた。時間に余裕があるわけではないが、今回はその理由を探ってみた。
プログラムは下記のようなものだ。かなり単純化してはあるが、構造は同じである。
----------------------------------------------------------------
vector v;
v.push_back(10);
v.push_back(-2);
v.push_back(3);
v.push_back(-10);
for(vector::iterator it = v.begin(); it != v.end(); it++){
if(*it < 0){
v.erase(it--);
}
//この後、エラーが起こる
}
----------------------------------------------------------------
「イテレータが不正」とのことなので、とりあえずブレークポイントをしかけてみるものの、「it」には特に問題がない。
そこで試しに、「begin()」と「end()」を取得してみた。
----------------------------------------------------------------
if(*it < 0){
v.erase(it--);
vector::iterator b_it = v.begin();//vの最初の要素を表すはず
vector::iterator e_it = v.end();//vの最後の次の要素を表すはず
}
----------------------------------------------------------------
すると、「b_it」は予想通り最初の要素を表したが、「e_it」は最後の要素を表していた。
本来は最後の次の要素を表さなければならないので、ここで「end()」が狂っていることがわかる。
なぜそうなるのか、詳細は分からないが、結局イテレータでループを回しつつ「erase()」することで問題が出ることは分かった。
ので、ループカウンタを使っての配列アクセスにしつつ削除の際はイテレータを取得して「erase()」するようにした。
結果、エラーは起こらなくなった。詳細については後日調べようと思う。
----------------------------------------------------
for(unsigned int i = 0; i < v.size(); ){
if(v[i] < 0){
vector::iterator it = v.begin() + i;
v.erase(it);
}else{
//erase()は後ろの要素を詰めるので、erase()しなときのみカウンタを回す
i++;
}
}
----------------------------------------------------
上記は修正結果である。
あまり良いプログラムには見えない。
STLのvectorを利用した際に起こるもので、要素の削除に関連したもの。
前にも何度かやっていて、よく分からずにその当時は投げていた。時間に余裕があるわけではないが、今回はその理由を探ってみた。
プログラムは下記のようなものだ。かなり単純化してはあるが、構造は同じである。
----------------------------------------------------------------
vector
v.push_back(10);
v.push_back(-2);
v.push_back(3);
v.push_back(-10);
for(vector
if(*it < 0){
v.erase(it--);
}
//この後、エラーが起こる
}
----------------------------------------------------------------
「イテレータが不正」とのことなので、とりあえずブレークポイントをしかけてみるものの、「it」には特に問題がない。
そこで試しに、「begin()」と「end()」を取得してみた。
----------------------------------------------------------------
if(*it < 0){
v.erase(it--);
vector
vector
}
----------------------------------------------------------------
すると、「b_it」は予想通り最初の要素を表したが、「e_it」は最後の要素を表していた。
本来は最後の次の要素を表さなければならないので、ここで「end()」が狂っていることがわかる。
なぜそうなるのか、詳細は分からないが、結局イテレータでループを回しつつ「erase()」することで問題が出ることは分かった。
ので、ループカウンタを使っての配列アクセスにしつつ削除の際はイテレータを取得して「erase()」するようにした。
結果、エラーは起こらなくなった。詳細については後日調べようと思う。
----------------------------------------------------
for(unsigned int i = 0; i < v.size(); ){
if(v[i] < 0){
vector
v.erase(it);
}else{
//erase()は後ろの要素を詰めるので、erase()しなときのみカウンタを回す
i++;
}
}
----------------------------------------------------
上記は修正結果である。
あまり良いプログラムには見えない。
PR
No.8
2009/08/16 (Sun) 19:50:33
また大して調べずに書いていてなんですが、
GetMessage:何かメッセージが来るまで待機
PeekMessage:メッセージが来なくても続行
という違いがあったような気がします。
とりあえず適当に本を眺めながら打ち込んでいたら、どうもうまく動かない。というよりも入力を受け付けない。終了できない。
何かと思ったら、PeekMessageでPM_NOREMOVEを指定しているのにうまく終了させるコードを挟んでいなかったんですね。常に戻り値がTRUEで、だから終了せず回り続けてしまった。
ということでPM_REMOVEを指定。…すると今度は数回のループで終了。メッセージが全て取り除かれてメッセージ・キューが空っぽになったからFALSEが返ってきた、と。簡単に対処しましたが、どちらにしてもエラーメッセージはそれはそれとして処理するようにしなければ……。
こんな基本的なところで躓いているようではダメですね。
展開結果を考慮せずに内部リンケージの変数にアクセスするインライン関数を作って、外のファイルからアクセスしようとして乙ったり。展開されたらアクセスできないの分かるだろうに……
精進あるのみ……というより、落ち着け、自分。
GetMessage:何かメッセージが来るまで待機
PeekMessage:メッセージが来なくても続行
という違いがあったような気がします。
とりあえず適当に本を眺めながら打ち込んでいたら、どうもうまく動かない。というよりも入力を受け付けない。終了できない。
何かと思ったら、PeekMessageでPM_NOREMOVEを指定しているのにうまく終了させるコードを挟んでいなかったんですね。常に戻り値がTRUEで、だから終了せず回り続けてしまった。
ということでPM_REMOVEを指定。…すると今度は数回のループで終了。メッセージが全て取り除かれてメッセージ・キューが空っぽになったからFALSEが返ってきた、と。簡単に対処しましたが、どちらにしてもエラーメッセージはそれはそれとして処理するようにしなければ……。
こんな基本的なところで躓いているようではダメですね。
展開結果を考慮せずに内部リンケージの変数にアクセスするインライン関数を作って、外のファイルからアクセスしようとして乙ったり。展開されたらアクセスできないの分かるだろうに……
精進あるのみ……というより、落ち着け、自分。
No.7
2009/08/16 (Sun) 19:50:11
今更だけど、メンバ関数コールバックは、
&クラス名::メンバ関数名
ってやらないとアドレス受け取れないらしいね。
……3月に書いたことにツッコんでもなぁ。
&クラス名::メンバ関数名
ってやらないとアドレス受け取れないらしいね。
……3月に書いたことにツッコんでもなぁ。
No.6
2009/04/24 (Fri) 00:41:35
自分は、あまりにもプログラマに向いていない。
普段から感じることだが、先輩と話をすると強くそれを感じる。
手段として、ゲームを作るために自分はプログラムを書く。
とはいえ、プログラミングが嫌いなわけではない。
それでも、どこまでも貪欲になれない自分はプログラマとして不適であるのだろうと思う。
なんにでもそうだが、私は貪欲に情報を得ようと動くことがない。
本当に、一切ない。
新しいことに興味はあっても、新しいことを渇望しない。消極的な興味しか持たない。そこに実行力と繋がる力は発生しない。
ゆえに、私は新しいことを得ない。
ニュースを見ない。
先輩は色々な物事について、段階的に掘り下げ追求して調べていく。新しいことにも目を向け、常に貪欲に情報を掴んでいくスタイル。
私は自分の使っている言語についてすら、情報を仕入れようとしない。まったく、そんな気にならない。
かなり絶望的だ。
でも、そこに焦りはあっても、実行へ移ろうという思いは発生しない。
致命的なまでに、私は欲がない。のかもしれない。
それでも、ないわけではない。諦めているだけなのかもしれない。
ならば、克服していかなければならないのかもしれない。
無欲さの矯正をしなければならないのかもしれない。
普段から感じることだが、先輩と話をすると強くそれを感じる。
手段として、ゲームを作るために自分はプログラムを書く。
とはいえ、プログラミングが嫌いなわけではない。
それでも、どこまでも貪欲になれない自分はプログラマとして不適であるのだろうと思う。
なんにでもそうだが、私は貪欲に情報を得ようと動くことがない。
本当に、一切ない。
新しいことに興味はあっても、新しいことを渇望しない。消極的な興味しか持たない。そこに実行力と繋がる力は発生しない。
ゆえに、私は新しいことを得ない。
ニュースを見ない。
先輩は色々な物事について、段階的に掘り下げ追求して調べていく。新しいことにも目を向け、常に貪欲に情報を掴んでいくスタイル。
私は自分の使っている言語についてすら、情報を仕入れようとしない。まったく、そんな気にならない。
かなり絶望的だ。
でも、そこに焦りはあっても、実行へ移ろうという思いは発生しない。
致命的なまでに、私は欲がない。のかもしれない。
それでも、ないわけではない。諦めているだけなのかもしれない。
ならば、克服していかなければならないのかもしれない。
無欲さの矯正をしなければならないのかもしれない。
No.5
2009/04/13 (Mon) 09:39:30
――コギト・エルゴ・スム
「我思う、ゆえに我あり」
と訳されるルネ・デカルトの言葉ですが、実際これは妥協点なのかな、と私は思います。
彼はひたすら色々なものを否定してみて、残された明らかなものとして「考える自分」を挙げました。デカルトの著作は一切読んでいないので、詳細は分からず知ったかぶりもいいところですが。
ともあれ、その「考える自分」というものも含めあらゆるものは否定しようとすることができます。重要なのは否定できるわけではなく、“否定しようとできる”こと。
いったい何が否定できないのかというと、それは唯一絶対のものではありませんが、普段思考するあらゆることの根底部分に位置していることです。これを否定してしまうとどんなことにも回答することができなくなる、というもの。その1つとしてデカルトは「我」を挙げたのではないでしょうか。
先ほど妥協点と書きましたが、それでもデカルトの答えは素晴らしく秀逸なもので、「我」を否定してしまうといかなるものにも回答を出すことができなくなります。
数学は人間が作った概念ですが、そこにはルールが存在します。そのルールを正しいと仮定して次のステップへ進むわけです。
人間の思考は全て同様で、なにかしらの仮定を当然のこととしてその上に思考を積み上げていくのです。
否定することが出来ないものは複数ありますが、その多くはループに嵌ってしまいます。最も簡単な例としては、
全ては肯定することが出来ない。
ならば、“全ては肯定することが出来ない。”という言葉も肯定することが出来ない。
これは以下ループ、エンドレスです。処理の戻ってこない再帰関数のようなもの。
GNU is Not Linuxと同じです。
勢いだけで書いているためにおかしくなってきていますが、
結局のところ、人が最初に仮定として、気づかずに当然としているものは自分自身なのではないかというのが私の思いで、
これがすなわち「我思う、ゆえに我あり」ということなのではないだろうか。
そういうことです。
これをスパッと言い切ったデカルトという人物は確かに大きな存在でしょう。
私はフランシス・ベーコンの方が好きですが。体調悪いのに雪ではしゃいで体悪くして人生終了とか楽しいじゃないですか。
「我思う、ゆえに我あり」
と訳されるルネ・デカルトの言葉ですが、実際これは妥協点なのかな、と私は思います。
彼はひたすら色々なものを否定してみて、残された明らかなものとして「考える自分」を挙げました。デカルトの著作は一切読んでいないので、詳細は分からず知ったかぶりもいいところですが。
ともあれ、その「考える自分」というものも含めあらゆるものは否定しようとすることができます。重要なのは否定できるわけではなく、“否定しようとできる”こと。
いったい何が否定できないのかというと、それは唯一絶対のものではありませんが、普段思考するあらゆることの根底部分に位置していることです。これを否定してしまうとどんなことにも回答することができなくなる、というもの。その1つとしてデカルトは「我」を挙げたのではないでしょうか。
先ほど妥協点と書きましたが、それでもデカルトの答えは素晴らしく秀逸なもので、「我」を否定してしまうといかなるものにも回答を出すことができなくなります。
数学は人間が作った概念ですが、そこにはルールが存在します。そのルールを正しいと仮定して次のステップへ進むわけです。
人間の思考は全て同様で、なにかしらの仮定を当然のこととしてその上に思考を積み上げていくのです。
否定することが出来ないものは複数ありますが、その多くはループに嵌ってしまいます。最も簡単な例としては、
全ては肯定することが出来ない。
ならば、“全ては肯定することが出来ない。”という言葉も肯定することが出来ない。
これは以下ループ、エンドレスです。処理の戻ってこない再帰関数のようなもの。
GNU is Not Linuxと同じです。
勢いだけで書いているためにおかしくなってきていますが、
結局のところ、人が最初に仮定として、気づかずに当然としているものは自分自身なのではないかというのが私の思いで、
これがすなわち「我思う、ゆえに我あり」ということなのではないだろうか。
そういうことです。
これをスパッと言い切ったデカルトという人物は確かに大きな存在でしょう。
私はフランシス・ベーコンの方が好きですが。体調悪いのに雪ではしゃいで体悪くして人生終了とか楽しいじゃないですか。