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

No.3ベストアンサー
- 回答日時:
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の隣にあって、それが悪さをしているということだとすると、リンクの順序や、他の関数の変数の順序を入れ替えるだけで、問題が解決したように見えることがあります。
なので、問題の関数がそのままでも、一見問題が出たり出なかったりもします。
配列は hairetu[20] = {0};として初期化していますので、おそらく問題はないはずなのです。20になった場合、if文で0に戻すようにしていますので。
でも、問題が出ていたのが配列の箇所なんですよね・・・。
>なので、ほかの関数で定義されている static な(多分、配列)変数への代入が間違って、zを壊したか、あるいは、ポインタ経由の代入で、ポインタが正しいところを指していなかったかだと思います。
>なお、他の関数で定義されている変数が、たまたまzの隣にあって、それが悪さをしているということだとすると、リンクの順序や、他の関数の変数の順序を入れ替えるだけで、問題が解決したように見えることがあります。
>なので、問題の関数がそのままでも、一見問題が出たり出なかったりもします。
この辺りが非常に怖いため、もう一度、他の関数含めて宣言を見直してみたいと思います。分かり易く書いていただきまして、ありがとうございました。
No.4
- 回答日時:
まあ static だと「値が保存されている」と思い込んじゃうからかえって問題を見つけにくいかもしれんのだけど....
「色々試しました」という中で, その変数の値を出力しようとは思いませんでしたか?
そういえばしませんでした。
元々ポインタの方に問題あるとばかり思っていたので、異常があったら出力することを覚えた方が良さそうですね。
ありがとうございました
No.2
- 回答日時:
>Static変数の値って、どんな時に壊れるんでしょう?
非staticな変数でもそうですが、ふつ~は勝手に内容が壊れることはありません。
# 人工衛星などで放射線等に晒されてメモリチップ内の値が変わる。とかいうのでなければ。
CPUは「指示された通り」に愚直に値を書き換えます。
そこにはプログラマの意図が割り込むスキはありません。
「書かれた通りのコード」に従って動作するだけです。
# 書かれたコードがプログラマの意図と違っていても…です。
まぁ、最近のCPUとOSだとメモリ領域の一部を保護したりとかしている事もありますが…。
# static変数を保護している。とかではないです。プロセスに割り当てていないメモリアドレスへのアクセスを禁止していたり、OSのコード部分を書き換えたり出来ないように…などです。
って事で、どこかで貴方のコードが破壊するように指示しているのでしょう。
ポインタの理解が怪しいようですのでその辺りで間違いがあるとか、
配列の添え字をミスして他のものが書き換えているか……そういったところかと。
掲示された例だと…
hairetu[x] = zahyouX;
でxを参照する前にxの値をどこかで書き換えているのでしょう。
グローバル変数にしていて、全く関係無いところで書き換えている。なんてのはよくあるミスです。
# 衝突しそうな単純な変数名にしていると探すのは大変でしょうねぇ……。
VisualStudioで特定の領域が書き換えられたらブレークする。とかできましたかね…。
http://dixq.net/forum/viewtopic.php?f=3&t=11327
static変数ならプログラム起動時にはアドレス確定しているハズですから、上記の方法が採れるんじゃないですかね。
# 使ったことありませんけど。
いえ、そもそもcppを跨ぐようなグローバル変数を使っていない・・・はず! です。でも、staticを入れたつもりで入れていない。なんてミスがありそうです。
>VisualStudioで特定の領域が書き換えられたらブレークする。>とかできましたかね…。
少し内容が難しそうですが、なんとか理解したいと思います。ありがとうございました。
No.1
- 回答日時:
どこかの処理で、そのstatic変数を壊してるだけでは?
そのstatic変数を使用する直前にでも、その値が想定するものかどうか確認するコードを書き加えて確認してみてはどうですか。
この回答への補足
意味が分からないのですが、あ、回答の話ではなく。
昨日・一昨日あわせて10時間くらい悩んで何回もプログラムを再起させてできなかったのに、以前と同じコードにしたら今はあっさり動くんです・・・、なんで・・・。
Static変数の値って、どんな時に壊れるんでしょう?
おそらく全く解決していませんが、何が何だか分からない内に動くようにはなりました。次からは値を確認することを癖にしたいと思います。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- Java java final 1 2022/06/10 22:49
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# int tff(int clk) { static int state = 0; //状態 stat 1 2022/07/11 21:14
- C言語・C++・C# 変数の初期化について 5 2022/10/02 08:55
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
#pragmaについて
-
ビット演算について
-
C++変数宣言時のコンストラクタ...
-
C++でデータの途中から読み込み
-
仮想基底クラスをもつクラスの...
-
errorC2228 CColorDialog
-
デフォルトコンストラクタで分...
-
文字列の検索&排除をするプロ...
-
binファイルが軽くなる変数への...
-
この型変換の内容がわかりませ...
-
int型とchar型について
-
static宣言について
-
Schemeのコンストラクタの引数は?
-
FORTRANのCOMMONについて
-
long型のデータをバイト型の配...
-
構造体を型の異なる構造体に代入
-
構造体の勉強をしているのです...
-
整数から16進数への変換 現在c...
-
Pythonです。 monster ballを定...
-
Visual C++を 用いたテキストフ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
「#undef」と「#define」の使い...
-
C言語 構造体の中に共用体を定...
-
構造体のデータを丸ごとコピー...
-
VBAの変数のデータ型を変更する...
-
日付チェック関数について
-
整数から16進数への変換 現在c...
-
typedefをプログラム中で解除す...
-
値が代入されてない時
-
C++ 構造体の一括初期化 {0}
-
VBAで符号無し整数
-
long型のデータをバイト型の配...
-
変数の初期化について
-
1バイトデータの読み出しについて
-
charとucharの違い
-
VBAにてcolorindexを変数に格納...
-
異なる構造体のデータのコピー
-
構造体を型の異なる構造体に代入
-
構造体にする理由・利点・使用例
おすすめ情報