• ベストアンサー

ソートについて(その他質問あります)

こんにちわ。Cプログラム初心者の学生です。 友達のプログラムについての質問なので詳しくは説明できませんが、よろしくお願いします。 ソートのプログラム(いろいろなソート)を作ったのですが、ソートする範囲を6万以上(0~59999)にすると必ずエラーが出てプログラムが終了してしまいます。 最終的には10万以上の値をソートしたいのですが、エラーが出て困っています。 値の生成についてはランダムで、配列に格納してやるという形にしています。 やはり、配列数が0万以上はサポートしていないのか、メモリの問題でしょうか? これは私の質問ですが、処理の高速化についてアドバイスいただきたいです。私が知ってるのは、掛け算割り算はあまり使わない、なるべく値の受け渡しはポインタを使った方がいい・・・という程度です。 あとこれから初心者Cプログラマとしてステップアップしていくために重要なこととかあれば教えて下さい。 ちなみに今はMFCについて少し勉強しています。 まとまりの無い文になってしまいましたが、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.2

配列変数をAUTO変数として宣言していませんか? main() { int array[100000]; .... } AUTO変数はスタックという特別なメモリ領域にとられるため、大きなサイズを 確保すると不足する場合があります。下記のようにしてみてください。 static int array[100000]; 尚、通常大きなサイズの変数を利用するときは、malloc()関数を使って 領域を確保します。説明は省略しますので、調べてみてください。 以下に、参考URLを載せておきます。参考にしてください。 http://www.pro.or.jp/~fuji/mybooks/cpro/cpro.4.5.2.html http://ecoeng.im.kindai.ac.jp/c/ http://homepage1.nifty.com/toshio-k/prog/c/

nobori55
質問者

お礼

回答ありがとうございます。 なるほど。static変数で宣言するとは気づきませんでした。 でも、スタック(後入れ先だしですよね?)というメモリ領域ではなぜ不足するのか・・・。もし知っていればご回答下さい。(初心者的な質問ですいません) 私も、malloc()関数で領域を確保してみればと友達に言ったのですが、なんか難しそうといって敬遠していました。 私自身も勉強しないとダメですね・・(笑) 有難うございました。また何かあれば質問させていただきますので、その時はよろしくお願いします!!

その他の回答 (3)

  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.4

#2です。 VCがどうなのかは知りませんが、あくまでも一般論です。 プログラムのメモリ配置は、こちらに書かれているようになります。 http://www1.cts.ne.jp/~clab/hsample/Point/Point19.html このうち、スタックサイズは通常リンク時に指定されたサイズとなります。 そしてスタックは、関数の戻り番地や引数、AUTO変数などに使われます。 ですから、AUTO変数のサイズを多くとったり、関数呼び出しのネスティングが 深くなると、スタックを消費して「スタックオーバフロー」になることが あります。クイックソートなどの再起呼び出しを行う処理では、 このネスティングが深くなるのでその可能性が高くなります。 AUTO変数の配列だけのせいだけではなく、このことも一因かもしれませんね。

参考URL:
http://www1.cts.ne.jp/~clab/hsample/Point/Point19.html
nobori55
質問者

お礼

またまたご回答有難うございますm(__)m 初心者にとったらまだ難しい内容ですが、なんとなくですがわかりました。 本当に助かりました。 初心者から脱却するために精進します。 また何かありましたらよろしくお願いします。

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.3

環境に関する記述がいっさい無いので答えにくいのですが… MFCとの記述があるので、32ビット系WindowsOSを想定します。 16ビット版MFCなんてことはないですよね? > エラーが出て困っています 実行時エラーですか?コンパイル/リンクエラーですか? ソート対象のデータは静的な配列ですか?動的メモリブロックを配列として参照しているのですか? ソート対象データは一括して処理しているのですか?部分ソートを繰り返しているのですか? そもそも、OSとコンパイラは何ですか? ソート対象データの型は? > 処理の高速化についてアドバイスいただきたいです > なるべく値の受け渡しはポインタを使った方がいい コンパイラの最適化が有効に機能するようにトリッキーなコードを書かない。 かけ算/割り算をさけるためにトリッキーなコードを書いてしまったら最適化が有効に機能しないことがあります。 素直に、シンプルに、定石通りに書いたプログラムが結局早く実行されます。 > 初心者Cプログラマとしてステップアップしていくために重要なこと 素直にアルゴリズムを記述することが第一歩です。 Cのコードでどんなにがんばってもアセンブラ高速アルゴリズムを使ってで書いたコードより速くすることはできません。 どんなにがんばってトリッキーなコードを書いても設計段階で高速化を意識したプログラムには勝てません。 CPUのクロックがGHzを超えているような時代に数クロック速くするためにトリッキーなコードを書くのはナンセンスです。

nobori55
質問者

お礼

すいません・・。環境の記述は必須ですよね。 WindowsOS、コンパイラはVC6.0、実行時のエラー、AUTO変数で動的、その他は友達の作ったプログラムをじっくり見てみないと分かりません。 処理の高速化についてですが、無理にトリッキーなコードを書く必要はないんですね。コンパイラの最適化を阻害してしまいかねない、ってことですよね。 SEを目指す者として、勉強を重ねないとダメですね。 ほんと初心者的な質問を詳しく回答していただいて有難うございました。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.1

ソートで考えられるのは配列の添え字32767オーバー、65535オーバー、配列のメモリ-オ-バー位ですね。

nobori55
質問者

お礼

さっそく、回答ありがとうございます。 やっぱりメモリオーバーですか。 いろいろ改善してみる必要がありますね。 有難うございました!!

関連するQ&A

  • c言語 配列 や ソート datファイル読み込みについて

    初投稿でC言語初心者なのでよろしくお願いします。 課題でdatファイルから100万個の数字を読み込んで、ソートのタイムを競うのがでました。 ソートのアルゴリズム等は分かるのですが、100万個の数字を読み込むのがわかりません。 datファイルには、縦にずらっと数字が並べられていてどこを区切り文字としてとりだすのとか。 int配列も100万個も格納できないので3次元配列つかうのかなと思ってみたりしてます。 どうやって格納すればソートで使いやすいかご教授お願いいたします。

  • クイックソートのプログラム

    『n個のデータを配列a[0],a[1],...,a[n-1]に読み込んでおき、クイックソートで降順に並べ替えるプログラムを作る。』 という問題が出ているのですが、C言語初心者の私には全くわからなくて困ってます。 このプログラムを教えてください!お願いします!

  • ソートに関する質問です

    C言語でのプログラム作成の課題が解けなくて困っています。 バブルソートを使って、1000000個の整数データを昇順に並べ替えるプログラムを作成するというものです。 自分なりに作成したプログラムは、mallocでデータを格納する動的領域を確保して、後はシンプルにバブルソートの処理を行っています。 データ数が5,6万程度なら正常な動作が確認できるのですが、それより大量のデータ数だと、処理に時間が掛かりすぎるせいか、もしくは処理しきれずに動かなくなってしまったのか分かりませんが、プログラムの処理がいつまでたっても終わりません。 おそらくバブルソートの2重ループのあたりで、膨大な処理になってしまうのだと思うのですが、この問題についての改善策をどなたかご教授いただけませんでしょうか。

  • java ソート

    java ソート ソートプログラムを作ってみましょう ? double型の配列とメソッドを持つクラスを定義 ? コンストラクタで配列を初期化(0.0で初期化) ?配列を昇順,降順に並び替えるメソッドを持つこと ? 2種類のメソッドを持っても良い ? 引数の値で変えても良い ? ソート済み配列をチェックするメソッドを持つこと ? 1000000要素程度のソーティングで時間計測 課題です 全く手が出せず困ってます・・・。 ヒント、手順、解答 なんでも良いので、救いの手をお願いします!!

  • 配列のソート

    下記のような形でデータを取得し結果を配列に格納し、 降順にソートしたいのですが、いい方法が見つかりません。いい方法はあるでしょうか。よろしくお願いします。 テーブル構造(test) ID|name |point|area| ==================== 1 |Aさん|56 | A | 2 |Bさん|12 | B | 3 |Cさん|24 | B | 4 |Dさん|34 | B | $sql = "select * from test"; $result = mysql_query($strSQL); while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { ここで配列に格納 } 配列への格納方法と、pointの降順にソートする 方法が知りたいです。 最終的に、Aさん、Dさん、Cさん、Bさんと なるようにしたいです。

    • ベストアンサー
    • PHP
  • 二次元配列のソート PHP

    タイトルのとおりソートを行ってくれる関数を探しております。 $buf[][]の二次元配列の変数を日付の降順に並べ替えたいのですが、そういった関数は用意されていますか? sort()、rsort()では不可能かと思います。 以下、二次元配列の値です。配列三番目の日付の降順で再格納したいです。 ( [0] => Array ( [0] => 1[1] => name1 [2] => 2006-08-18 ) [1] => Array ( [0] => 2 [1] => name2[2] => 2006-08-28 ) [2] => Array ( [0] => 3[1] => name3 [2] => 2006-08-18 ) [3] => Array ( [0] => 4 [1] => name4[2] => 2006-08-18 ) よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • 配列のソートの質問です。

    配列のソートの質問です。 初心者です。よろしくお願いいたします。 //---テキストファイルの1行目を読み込んで配列にいれました----------- for($i = 1; $i < 51; $i++){ $fq = fopen("../4c/4c$i/+score.txt", 'r'); $fr = fgets ($fq); $frr = rtrim($fr); $line[$i-1] = "$frr <font color=blue>4c$i</font>"; fclose ($fq); } //-----その配列をソートしました--------------- rsort($line,SORT_NUMERIC); foreach ($line as $tmp){ print "$tmp<br>"; } //---すると 22,問題番号→,1239,2010/06/22/Tue/11/41/24 4c1 22,問題番号→,1239,2010/06/22/Tue/11/40/54 4c26 22,問題番号→,1239,2010/06/22/Tue/11/42/48 4c28 22,問題番号→,1239,2010/06/22/Tue/11/52/33 4c23 22,問題番号→,1239,2010/06/22/Tue/11/42/15 4c20 //----以下省略------------------------------- となりました。 各行の先頭が 22 で同じとき 2010/06/22/Tue/11/41/24 2010/06/22/Tue/11/40/54 2010/06/22/Tue/11/42/48 2010/06/22/Tue/11/52/33 2010/06/22/Tue/11/42/15 の早い順にソートするには どうしたらよいでしょうか? お教えください。

    • ベストアンサー
    • PHP
  • 1次元配列のソート方法

    配列のソートメソッドについて質問させていただきます。 VB.NET初心者なので日本語がおかしいかもしれませんが、宜しくお願いいたします。 データテーブルが格納されている配列があり、 その配列をソートしたいと思っています。 データテーブルの中に「NO」と「ID」というフィールドがあります。 NOで昇順し、NOが同じだったらIDの昇順でソートといったことがしたいのですが、 条件によっては上手くいきません。 よろしければ、教えていただけないでしょうか? また、もっと効率の良い方法とかありましたら、具体的はソース等教えていただけないでしょうか? 宜しくお願いいたします。 [例] workDT() ← 元のデータテーブル配列 Dim Datatable(workDt.Rows.Count-1) As DataTable ← ソート後のデータテーブル配列 Dim tmpDatatable(workDT.Rows.Count-1) As DataTable ← 途中で使うデータテーブル配列 Dim NO(workDT.Rows.Count-1) As Integer ← 元のデータテーブル配列の各「NO」フィールドを格納する配列 Dim ID(workDT.Rows.Count-1) As String ← 途中で使うデータテーブル配列の各「ID」フィールドを格納する配列 Dim Index(workDT.Rows.Count-1) As Integer ← インデックスに使用 ' IDでソート For i = 0 To workDt.Length - 1 ID(i) = workDt(i).Rows(0).Item("ID") Index(i) = i Next ' 配列をIDでソート Array.Sort(ID, Index) ' ソート後配列をテンプ配列に格納 For i = 0 To workDt.Length - 1 tmpDatatable(i) = workDt(Index(i)).Copy Next ' NOでソート For i = 0 To tmpDatatable.Length - 1 NO(i) = tmpDatatable(i).Rows(0).Item("NO") Index(i) = i Next ' 配列をNOでソート Array.Sort(NO, Index) ' ソート後配列を格納 For i = 0 To tmpDatatable.Length - 1 Datatable(i) = tmpDatatable(Index(i)).Copy Next これで各配列を初期化します。 workDTに5つのデータテーブルが入っていて workDT(0):ID=3、NO=1 workDT(0):ID=1、NO=5 workDT(0):ID=2、NO=5 workDT(0):ID=4、NO=5 workDT(0):ID=5、NO=7 (IDは重複不可設定、NOは重複可設定です。) とした場合、NOのソートのところで変な順番になってしまいます。 Array.Sort(NO, Index) このメソッドは同じ値だった場合、何を優先してソートしているのでしょうか? 環境はWindowsXPSP3とVB2005です。

  • 構造体配列のクイックソート

    こんにちわ。 構造体配列のリストを ポインタのつなぎ変えによるクイックソートで 以下のようなソートをしたいのですが、悩んでおります。 struct info { int count; struct info *prev; struct info *next; }; int main () { struct info info[5]; /* 初期値設定 */ quick_sort(info, 0, 5); return 0; } 上記のようにして、クイックソートをしたいのですが、 よくあるクイックソートだと 例えば初期値を <配列のindex>要素の値を <0> <1> <2> <3> <4> 5 1 4 3 2 などと定義した場合 普通のクイックソートだと <0> <1> <2> <3> <4> 1 2 3 4 5 というように並び変えられてしまい <配列のindex>と 要素の値の組み合わせが変わってしまいますが、 この組み合わせを変えず、 struct info *if; if = info; for (i=0; i<MAX; i++){ printf("%d", if->count); if = if->next; } printf("\n"); とすることで、indexとしては昇順になっていないが *nextをたどっていくことでちゃんと目的の値の昇順になっている というのを実現したいのですが、ポインタのつなぎ変えか何かが 間違っているようで うまいことできていません。 どなたかご教授いただけますでしょうか。 申し訳ありませんが、よろしウお願いいたします。

  • 構造体のリストをソートしたい。

    ある名簿のリストを作りました。 以下のような構造体で、 typedef struct meibo{ char name[10]; int old; struct meibo *next; }MEIBO; これを、ポインタp->next->nameをたどっていって、名前が辞書順になるようにリストを作ったのですが、 これを年齢順にソートして表示させたいんです。 どんな方法があるんでしょうか? 一旦すべてを配列に格納して、クイックソート…とかも考えたのですが、すごく領域をとるし、なんか2度手間(最初から配列に順に格納していけばよかったなぁ・・・と。 それでもやっぱり最初から名列順にするときから配列に入れておくほうがいいのでしょうか? 教えてください。 (最初から年齢を比較してリストを作れば・・ってのはなしで、名列順のリストが存在するものとしてください。)