- 締切済み
使わなくなった変数に違う値を入れるのはマズイ?
CやJAVAのような、厳密な型の存在しない言語(Perl、PHP、Javascriptなど)についての質問です。 プログラミングをしていて、途中である変数が要らなくなることがあります。これを、せっかく宣言したので別の値、それも型が違ったりプリミティブ型の値を入れてたのにオブジェクト型を入れるとか、そういう使い方をすることがあります。 例(Javascriptの場合) $hen = new Array(10); $hen[0] = 0; $hen[1] = 1; . . . for (i=0; i<10; i++) { print $hen[$i]; } //ここで配列henは要らなくなった。変わりに文字列が欲しい。 $hen = "String"; //せっかく変数henがあるので、これを入れ物として使う。 最近、C++の勉強をして、このようなケースで変数名との結びつきが無くなった変数の中身は、存在はするがアクセスする手段を失った「ゴミ」となるということを知りました。多くの言語も、同じような構造だとも知りましたが、同時に「ガベージコレクション」を装備している言語は、プログラムがその値が以降使われないと判断された場合は自動でその変数に割り当てているメモリを開放して処理速度向上を図る・・・とありました。では、例として挙げたケースでは、ガベージコレクションを装備していれば、ゴミは発生するがプログラムが自動でメモリを開放してくれるのでそこまで気にしなくても良い、という解釈で良いのでしょうか?私はPHPが得意なのですが、PHPは標準ではガベージコレクションを装備していないようなので、気をつけてプログラミングしようと思っているのですが。 余談ですが、「変数名と内容が一致しなくなるケースがある($arr = new Array();を後で$arr = "String";とするなど)からやめたほうが良い」という突っ込みはナシでお願いします。その点は承知していますので。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- notnot
- ベストアンサー率47% (4900/10359)
他の方も書かれてますが、良くないスタイルです。 名前一般に関しては、 ・同じ物は同じ名前で呼ぶ ・違う物には違う名前を付ける を原則だと思ってください。 #2の方の書かれた >プログラミングの基本の基本に「自動ガベージコレクションは、極力、発生させてはならない」と言うのがあります。 は、言語によってガベージコレクションの考え方が違うので、一般論ではありません。多くの動的言語では、メモリ管理をガベージコレクタに任せます。 >なぜなら「自動ガベージコレクション中は、本来のプログラムの動作が停止し、数秒~十数秒の間、まるでフリーズしたかのようになる」からです。 ガベージコレクタにメモリ管理を任せるのが普通では無い言語で、ガベージコレクションを発生させるとこういう状態になるかもしれません。
- chie65536
- ベストアンサー率41% (2512/6032)
まず第1に「要らないと思って変数を使い回しした後で、コードを変更する必要が出て、使い回しした後で元の変数の値が必要になっちゃった」って時に、すごく大変な思いをするでしょう。 変更作業には、本来行う必要のない「使い回しをしないように修正する作業」が伴います。もし使い回しをしていなければ「一切、する必要の無い作業」です。 その変更を行う前に「ここで値を参照しているのは、元の値を参照しているのか、使い回しした後の値を参照しているのか、どっちなのか覚えてない」って場合には「使い回しをしないように修正する作業」そのものが出来ません。 >最近、C++の勉強をして、このようなケースで変数名との結びつきが無くなった変数の中身は、存在はするがアクセスする手段を失った「ゴミ」となるということを知りました。 何か「大きな勘違い」をしていますね。 CやC++の場合の「存在はするがアクセスする手段を失ったゴミ」とは、例えば「newで宣言して確保はしたがdeleteで削除を行わないまま関数を抜けて参照スコープを失った変数」や「mallocで確保はしたがfreeしてないメモリ」などを言います。 これは、普通は「メモリリーク」と呼び「重大なバグ」に分類されます。 なぜなら「そういうプログラムが長く動き続けると、システムのメモリリソースを食い尽くして、システムそのものを停止させる事態」にまで発展するからです。 >自動でその変数に割り当てているメモリを開放して処理速度向上を図る・・・とありました。 プログラミングの基本の基本に「自動ガベージコレクションは、極力、発生させてはならない」と言うのがあります。 なぜなら「自動ガベージコレクション中は、本来のプログラムの動作が停止し、数秒~十数秒の間、まるでフリーズしたかのようになる」からです。 ブラウザで「送信」のボタンを押した瞬間、ガベージが起きて20秒以上も「画面が切り替わらず、反応がない」としたら、ユーザーはどういう行動に出るでしょうか?間違い無く言えるのは「黙ってじっと待ってる人は100人に1人居るか居ないか」でしょう。 >ガベージコレクションを装備していれば、ゴミは発生するがプログラムが自動でメモリを開放してくれるのでそこまで気にしなくても良い、という解釈で良いのでしょうか? ダメです。 ガベージコレクションを装備していようがいまいが、リークしたメモリは「システムを再起動するか、シャットダウンしない限り、メモリリソースを食い続ける」ので。 そういう解釈で居る限り「マトモなプログラマとして絶対に認めてもらえない」ので、もし将来プログラミングで食って行くつもりなら、考え方を改める必要があるでしょう。 てゆ~か「変数の使い回し」が許されるのは「組み込み用ファームウェアで、使えるRAMメモリが4キロバイトしかない」とかってプラットフォームでコードを書く時だけです。 現在主流の「WindowsPC」がプラットフォームの場合は「有り余るメモリを湯水のように使っても全然問題無い」ので「使い回しする必要が無い」です。
- Yune-Kichi
- ベストアンサー率74% (465/626)
変数の使い回しはやめた方がよいです。 コードを読む上で,「今何に関する情報が入っているのか」という情報が変更されてしまう上,将来コード変更する場合に大きな問題点になり得ます。 たとえば将来コードの変更を行い,"String"の代入後に配列の$henが必要になることがあった場合,どちらかの変数名を変更したり,配列の$henを別の変数に移したりしなければならなくなります。 古いCのようにループ変数をスコープに閉じこめることができない環境におけるループ変数iや,一部の組み込み環境のようにRAMの仕様を極限まで切り詰めなければならない場合を除けば,変数を使い回すことのメリットはなく,デメリットだけが存在すると考えて間違いないです。