• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:realloc関数の使い方)

realloc関数の使い方

このQ&Aのポイント
  • realloc関数を使用してメモリの拡張や縮小ができる
  • do~while文の中にrealloc関数を入れている
  • コンピュータとプレーヤの手を表示して、勝敗を判定し、勝/負/引き分け回数を更新している

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.3

なんというか…予想通りにハマっていますね…… 「realloc 使い方」で検索するといろいろ見つかると思われますが…… ・realloc()がNULLを返した場合は、第1引数で渡したメモリブロックは有効なまま。  ただし、メモリブロックのサイズ変更は失敗しています。 ・realloc()がNULL以外(有効なアドレス)を返却した場合は、第1引数で渡したメモリブロックは開放されている為に使用不可。新たなメモリブロックは指定したサイズに変更されいます。 # まぁ、細かいところ言うとmalloc()もrealloc()も指定サイズ以上のメモリブロックを確保している場合がありますが…。 ということで、まずrealloc()の戻り値で正常終了しているのかエラーだったのか確認する必要があります。 エラーだった場合は拡張に成功していないので、履歴を追加する処理を実施してはいけません。(バッファオーバーランしてぶっ壊します) 成功だった場合は、realloc()の第1引数に渡したポインタ変数にコピーすることでそのまま使用できるでしょう。 で、「毎回realloc()で拡張」はコストがかかるので、その辺りを改善した方がいいでしょう。 というのが http://okwave.jp/qa/q6961495.html の#2さんと#5さんが言っているコトです。 単純に拡張できなかった場合、メモリブロックのコピーが実施されるので動作が重い。 というのが払っているコストです。 # 単純に拡張できるかどうかは、使用したメモリの状況次第ですのでプログラマがどうこうすることはできません。

tanosiiC
質問者

お礼

結局printf文の%sと%cのタイプミスでした・・ 徹夜でやっていたので頭冷やして寝てから考えたらわかりました というかreallocとか関係なかった・・・ ありがとうございました。

tanosiiC
質問者

補足

realloc等で検索して書いているのですがなんかわからなくなってきました。 同じ変数でもできるみたいなんでこんな感じにしましたが駄目でした。 a = (int *)calloc(5, sizeof(int)); b = (int *)calloc(5, sizeof(int)); do{ jyanken(); /* じゃんけん実行 */ /* コンピュータとプレーヤの手を表示 */ printf("私は%sで、あなたは%sです。\n", hd[comp], hd[user]); judge = (user - comp + 3) % 3; /* 勝敗を判定 */ count_no(judge); /* 勝/負/引分け回数を更新 */ disp_result(judge); /* 判定結果を表示 */ retry = confirm_retry(); a = (int *)realloc(a, sizeof(int) * (draw_no+lose_no+win_no+1)); b = (int *)realloc(b, sizeof(int) * (draw_no+lose_no+win_no+1)); rireki(); }while(retry == 1);

その他の回答 (4)

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.5

まずは、malloc() や realloc() がどういう動きをするか「だけ」を 確認するようなプログラムを書いてみてはどうでしょうか。 じゃんけんゲームのことはいったんわきへどけて考えるのが得策のような気がします。

tanosiiC
質問者

補足

段階は大切ですね。 とりあえず配列を使ってみてただの%sと%cの打ち間違えだと気付きました。 いきなりつかったこと無い関数を組み込むことが間違いでした。

回答No.4

> まずいのはわかりましたがこの場合reallocをどうやって宣言すればいいのですか。 「宣言」ではなくて「使用」ですよね。 それを考えてコードを書くのが「プログラムを作る」ということです。 reallocに渡すポインタは何なのか、aに入っているポインタが使えない時でも、確保したメモリのポインタを持っている変数はありませんか? その編をうまく破綻しないように、ループの中でやりくりしましょう。

回答No.2

reallocでポインタが変更になった場合、a1とaは異なり、aはすでに使用できないメモリを指しています。 すると、ループで再びreallocのところに来た場合に、reallocに渡す元々のポインタがaではまずいですよね。 さらに、freeが解放する場合もaではまずいですよね。

tanosiiC
質問者

補足

まずいのはわかりましたがこの場合reallocをどうやって宣言すればいいのですか。

回答No.1

> a1 = (int *)realloc(a, sizeof(int) * (draw_no+lose_no+win_no+1)); reallocが返すポインタは、元のポインタとは異なる場合があります。同じポインタで、指定されたサイズのメモリが確保できるとは限らないからです。違うポインタが返された場合、元のポインタは使用できなくなっています。 ただし、realloc前にメモリに入っていたデータは、realloc後のメモリにコピーされます。なので、例えばrealloc前のa[0]とrealloc後のa1[0]は同じ値になります。この点が、mallocで新たにメモリを確保した場合との違いです。 a1とaが異なる場合を考えれば、どこに問題があるかわかるはずです。

tanosiiC
質問者

補足

具体的にどこに問題があるかを教えてもらえないでしょうか。 ちょっとわからないです。

関連するQ&A

専門家に質問してみよう