重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

現在、c言語とDXライブラリを使ってゲームを製作しています。

http://oshiete.goo.ne.jp/qa/8270456.html
前回、このような質問をさせていただき、原因らしき箇所を突き止める所までいきました。

と言いますのも、配列の要素を指定する箇所(分かり辛かったらすいません。要素数ではありません)に、static宣言された変数を入れるとなぜかプログラムが強制終了されてしまうのです。
加えて、DXライブラリのGetColor関数にも返ってきた色をStatic宣言された変数に格納すると、何故か指定された色と違う色が出てしまうことが分かりました。

なんとか、その関数が終わる度に値を格納したかったので、色々試しました。
直接Static宣言されていない変数を間に噛ませてみたり、同じcpp内にわざわざ別の関数を用意して、そちらでStatic宣言し、値を返してみたり、と色々とやったのですが上手くいきませんでした。

******************************************

int hairetu[20];
Static int z = 0;
int x = z-1+1

hairetu[x] = zahyouX;

(static宣言された変数zでhairetu[]の[]内を指定しようとするとダメ)
(上記のように意味のない計算をさせてstatic宣言されていない変数を間にかませてもダメ)

******************************************

結局の所、別のcppを用意して、ただ一つのStatic変数を+1していくだけの関数をくみ上げた所、上手くいったのですが・・・。何故このような事が起きるのでしょうか。

Static宣言された変数の決まりごと、もしくは、このような状態になってしまった原因など、見当がつきましたら教えていただけると有難いです。よろしくお願いします。

A 回答 (4件)

static 変数を破壊すると言うことですが、大抵の処理系では、static な変数はメモリ上にそのまま並んで(隙間はあるかもしれませんが)配置されます。



なので、わかりやすい例だと、

static int wk[20];
static int z;

か、

static int z;
static int wk[20];

と書いて、wk[20] = 10000;

とかすると、wk[] で確保されているはずの領域をはみ出して、z を書き潰します。
(多分、後者の書き方が下記つぶされる可能性が高いかと思います)

この場合、
static int z;
というのが関数の中で定義されていると、関数の中だけのスコープを持ちますから、他の関数で、直接zを壊すことはできません。
しかし、他の関数で、static 変数が定義されていると、変数は(関数ごとではなくて)全部の関数の static 変数がまとまって配置されることがあります(そういう処理系が多いと思う)

なので、ほかの関数で定義されている static な(多分、配列)変数への代入が間違って、zを壊したか、あるいは、ポインタ経由の代入で、ポインタが正しいところを指していなかったかだと思います。

なお、他の関数で定義されている変数が、たまたまzの隣にあって、それが悪さをしているということだとすると、リンクの順序や、他の関数の変数の順序を入れ替えるだけで、問題が解決したように見えることがあります。

なので、問題の関数がそのままでも、一見問題が出たり出なかったりもします。
    • good
    • 0
この回答へのお礼

配列は hairetu[20] = {0};として初期化していますので、おそらく問題はないはずなのです。20になった場合、if文で0に戻すようにしていますので。

でも、問題が出ていたのが配列の箇所なんですよね・・・。

>なので、ほかの関数で定義されている static な(多分、配列)変数への代入が間違って、zを壊したか、あるいは、ポインタ経由の代入で、ポインタが正しいところを指していなかったかだと思います。

>なお、他の関数で定義されている変数が、たまたまzの隣にあって、それが悪さをしているということだとすると、リンクの順序や、他の関数の変数の順序を入れ替えるだけで、問題が解決したように見えることがあります。

>なので、問題の関数がそのままでも、一見問題が出たり出なかったりもします。

この辺りが非常に怖いため、もう一度、他の関数含めて宣言を見直してみたいと思います。分かり易く書いていただきまして、ありがとうございました。

お礼日時:2013/09/20 12:48

まあ static だと「値が保存されている」と思い込んじゃうからかえって問題を見つけにくいかもしれんのだけど....



「色々試しました」という中で, その変数の値を出力しようとは思いませんでしたか?
    • good
    • 0
この回答へのお礼

そういえばしませんでした。
元々ポインタの方に問題あるとばかり思っていたので、異常があったら出力することを覚えた方が良さそうですね。

ありがとうございました

お礼日時:2013/09/20 12:24

>Static変数の値って、どんな時に壊れるんでしょう?



非staticな変数でもそうですが、ふつ~は勝手に内容が壊れることはありません。
# 人工衛星などで放射線等に晒されてメモリチップ内の値が変わる。とかいうのでなければ。

CPUは「指示された通り」に愚直に値を書き換えます。
そこにはプログラマの意図が割り込むスキはありません。
「書かれた通りのコード」に従って動作するだけです。
# 書かれたコードがプログラマの意図と違っていても…です。
まぁ、最近のCPUとOSだとメモリ領域の一部を保護したりとかしている事もありますが…。
# static変数を保護している。とかではないです。プロセスに割り当てていないメモリアドレスへのアクセスを禁止していたり、OSのコード部分を書き換えたり出来ないように…などです。

って事で、どこかで貴方のコードが破壊するように指示しているのでしょう。
ポインタの理解が怪しいようですのでその辺りで間違いがあるとか、
配列の添え字をミスして他のものが書き換えているか……そういったところかと。



掲示された例だと…
hairetu[x] = zahyouX;
でxを参照する前にxの値をどこかで書き換えているのでしょう。
グローバル変数にしていて、全く関係無いところで書き換えている。なんてのはよくあるミスです。
# 衝突しそうな単純な変数名にしていると探すのは大変でしょうねぇ……。

VisualStudioで特定の領域が書き換えられたらブレークする。とかできましたかね…。
http://dixq.net/forum/viewtopic.php?f=3&t=11327
static変数ならプログラム起動時にはアドレス確定しているハズですから、上記の方法が採れるんじゃないですかね。
# 使ったことありませんけど。
    • good
    • 0
この回答へのお礼

いえ、そもそもcppを跨ぐようなグローバル変数を使っていない・・・はず! です。でも、staticを入れたつもりで入れていない。なんてミスがありそうです。

>VisualStudioで特定の領域が書き換えられたらブレークする。>とかできましたかね…。

少し内容が難しそうですが、なんとか理解したいと思います。ありがとうございました。

お礼日時:2013/09/20 12:36

どこかの処理で、そのstatic変数を壊してるだけでは?


そのstatic変数を使用する直前にでも、その値が想定するものかどうか確認するコードを書き加えて確認してみてはどうですか。

この回答への補足

意味が分からないのですが、あ、回答の話ではなく。

昨日・一昨日あわせて10時間くらい悩んで何回もプログラムを再起させてできなかったのに、以前と同じコードにしたら今はあっさり動くんです・・・、なんで・・・。

Static変数の値って、どんな時に壊れるんでしょう?

補足日時:2013/09/20 07:44
    • good
    • 0
この回答へのお礼

おそらく全く解決していませんが、何が何だか分からない内に動くようにはなりました。次からは値を確認することを癖にしたいと思います。

ありがとうございました。

お礼日時:2013/09/20 12:38

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!