- ベストアンサー
ソート中に生じる変数の値の変化
C言語でソートを用いるプログラムを作成しているのですが,ソートを行った前後で,一部の変数の中身が勝手に書き換えられてしまっています. 例えば,int型で宣言されたix,iy,izという変数の中に格納された値は,ソートには何の関連性をもっていないにも関わらず,ソート後には全て同じ無茶苦茶な値に書き直されます.しかも,何故かこれ等の変数をグローバル変数にした途端に改善されました. ●何故この様な現象が生じてしまったのでしょうか? 加えて,少し類似した症状が,ソートの対象とする構造体にも観察されます.構造体のソートに使う変数自体に変化は見られず,ソート自体も正常に機能していることが確認されているのですが,構造体の他の一部の変数(double型)の値の一部分が0と1072693248に書き換えられます. ●この症状は一体何が原因で,どう改善すれば良いでしょうか? 幾分全く原因が分からない為,質問文自体もかなり曖昧になっていますが,宜しくお願いします.
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
ソートと言うからには、構造体の配列をソートしていると思います。 >しかも,何故かこれ等の変数をグローバル変数にした途端に改善されました. >●何故この様な現象が生じてしまったのでしょうか? 多分、ローカル変数の構造体の配列をソートしていると思います。 ソート時に要素数を間違ったり、1要素のサイズを間違ったりすると、構造体の配列よりも後方にある、無関係なローカル変数も「一緒にソート」されてしまいます。 つまりix,iy,izがソートしたい構造体配列の後方にあって「巻き添えでソートされた」のです。 で、ix,iy,izをグローバル変数に変えると、ソートしている構造体配列とは別の離れたメモリ空間に移動するため、ix,iy,izは壊れなくなります(が、代わりに、別の何かが壊れてしまっているでしょう。根本的解決にはなってません) 構造体をソートする際は「構造体1要素の大きさは、足し算で計算してはいけない」「要素の数は定数で書いてはいけない」と言う事に注意しましょう。 例えば、標準関数「qsort」は、 qsort(配列の先頭アドレス,要素数,1要素のバイト数,比較関数) になっています。 ここで typedef struct { char a; short b; int c; /* 比較キー */ char d[15]; } _T_ABC; _T_ABC ary[30]; という構造体配列をソートする時、 qsort(ary,30,sizeof(char)+sizeof(short)+sizeof(int)+sizeof(char)*15,cmp_func); や qsort(ary,30,1+2+4+1*15,cmp_func); と書いたら、メモリを壊します。 intが32ビットの環境では、この構造体は、メモリ上は 1バイト目:a 2バイト目:空き 3バイト目:bの一部 4バイト目:bの一部 5バイト目:cの一部 6バイト目:cの一部 7バイト目:cの一部 8バイト目:cの一部 9~23バイト目:d 24バイト目:空き となっていて、24バイトの大きさがあります。 しかし sizeof(char)+sizeof(short)+sizeof(int)+sizeof(char)*15 の計算結果は 1+2+4+1*15 で、22です。要素のサイズの大きさがウソなのでメモリを壊します。 正しくは qsort(ary,sizeof(ary)/sizeof(_T_ABC),sizeof(_T_ABC),cmp_func); と書かないとなりません。 >●この症状は一体何が原因 ソート作業により、メモリを壊しています。 つまり、余計な所をソートしているか、ソート自体が正しくありません。 >どう改善すれば良いでしょうか? ソート処理のバグを取りましょう。
その他の回答 (4)
- tatsu99
- ベストアンサー率52% (391/751)
結論から言えばプログラムに誤りがあります。 ソート中にその変数が書き換えられています。 具体的に何が原因かは、ソースを提示していただかないと判断できません。 例えば、以下のようなコーディングは、今回のように、全く関係ない変数を破壊する例です。 char data[10]; char data2[10]; strcpy(data,data2); //data2の中に何が入っているか不定
- arain
- ベストアンサー率27% (292/1049)
考えられる一番の理由は、メモリ管理(使用方法)の問題。 配列の宣言要素数を超えてアクセスしたり、小さいサイズの型に大きい当たりを無理に入れたりしようとした場合。 ポインタを使用しているのなら、アクセスしているところが間違っている場合もありえる。
- phoenix343
- ベストアンサー率15% (296/1946)
|●何故この様な現象が生じてしまったのでしょうか? 関数の中に書く変数と、グローバルに使えるようにした変数とでは、メモリに配置する場所が違います。つまり処理が改善されたのではなく、グローバルに置き換えたことで、その変数が影響を受けなくなっただけです。 |●この症状は一体何が原因で,どう改善すれば良いでしょうか? ソースを見せずに言われてもね ^^;) 例えるなら壊れた掃除機を持ってこずに「壊れた、直してくれる?」と言ってるようなもんですよ。
お礼
>例えるなら壊れた掃除機を持ってこずに「壊れた、直してくれる?」と言ってるようなもんですよ。 ご尤もです(苦笑) つたない質問文にご回答下さり,有り難う御座いました.
- okg00
- ベストアンサー率39% (1322/3338)
ソースを見ない限りはなんともいえませんが... ソースを公開してもらえませんか? デバッガを使って変数の動きを追えませんか? 変数はダイナミックですか?スタティックにしてみてはどうでしょうか? >1072693248 これが不定値っぽい気がしますけど。 ポインタを使って別の部分を書き換えていませんか?
お礼
明快な回答有り難う御座いました(´∀`;)ヾ あれ程の少ない情報量の中,明快な回答を提示して下さり有り難う御座います. 御陰様で無事解決しました(´・ω・)ノ