• ベストアンサー

mallocでメモリーを確保しようとすると暴走します

 組み込み系のプログラミングをやっているもので、malloc、freeを使って動的にメモリーの確保、開放を行っているのですが、途中で暴走してしまいます。 (mallocを呼び出すと、返ってこなくなります。)    そこでmallocの動作を見ようと、以下のプログラムを作って動作させると、while文の中を一周はするのですが、2週目のp2のポインターの値が返ってきません。(malloc関数の中でloopしています。)     /* 以下ソースコード */  char *p1;  char *p2;  char *p3;  char *p4;  while(1){    p1 = (char*)malloc(100);    p2 = (char*)malloc(100);    p3 = (char*)malloc(100);    free(p3);    p4 = (char*)malloc(100);    free(p4);    free(p2);    free(p1);  }  ※メモリーは、2k確保していあるので、サイズがオーバーしているということはないと思います。  ご質問ですが、  ・上記ソースコードで暴走するような要因がありますでしょうか?  ・malloc、free関数でメモリーの取得、開放の順番など注意しないといけないことがあるのでしょうか?  ・malloc、free関数等を自作とかされていますでしょうか?  どうぞよろしくお願い致します。

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

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

ルネサスのCコンパイラといっても、SHとH8とM16Cでは事情が違う気がしますが... ヒープ領域の使用状況をよく調べてみてください。 sbrkが呼び出されるたびに、呼出元(malloc, calloc, reallocの呼出元)を調べた方がよいでしょう。 例えば、ストリームの内部でもバッファリング用のメモリが割付けられるので、それがヒープを食いつぶしている可能性があります。 BUFSIZが512だとすれば、管理領域の4バイトを加えて、1ストリームあたり516バイト消費します。標準入力、標準出力、標準エラーの三つがスタートアップでオープンされるのであれば、516 × 3 = 1548となり、残りは500バイト。 100バイトを4回割付ければ416バイト必要なので、残りは84バイト。そして、5回目の割付けでしくじります。このとき、sbrkの定義が適切でなければ、何が起きても不思議ではありません。

youkun_1
質問者

お礼

ご回答ありがとうございます。質問に書いてあるプログラムが途中で止まる件は、解決しました。  stdlib.hをインクルードしていないという凡ミスでした。大変ご迷惑おかけいたしました。  しかしながら、本来のプログラムは相変わらず動作しません。 質問に書いたmalloc、free関数の中でループしている現象ではなく、sbrkで領域が確保できずエラーになってしまいます。  メモリーリークしているようなので、後は、回答者様のご意見を参考に、プログラムをもう一度見直してみます。  どうもありがとうございました。  

その他の回答 (3)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

「組込み系」というだけでは正確なことは何も分かりません。 処理系を具体的に補足してください。単なるコンパイラの製品名ではなく、ターゲットに合わせてmallocをカスタマイズする部分(例えばsbrkの自作など)があるはずですので、その内容についても合わせて補足してください。 なお、組込み系の多くは、「フリースタンディング環境」に分類されます。フリースタンディング環境では、規格上mallocは提供されませんので処理系の独自拡張になります。

youkun_1
質問者

補足

 ご回答ありがとうございます。コンパイラは、ルネサスのCコンパイラです。sbrkは提供されているものを使用していて、カスタイマイズしていません。またリアルタイムOSは、のせていません。  抽象的で申し訳ございませんが、質問に書いてあるプログラムくらいのものであれば、カスタマイズすることなく動作すると思っていました。  やはりスタックの問題でしょうか?  

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.2

if(( p1 = malloc(100)==NULL) break; のようにして,まずはプログラムミス(mallocの失敗の可能性に対応していない)なのか,他の要因なのかをまず見分けるべきでしょう. 余談ですが,mallocに(char*) はいりません. それと,メモリを2k確保と行っても,ヒープとスタックとがありますが,どっちにどれだけ割り当てているかわかりますか? 通常,mallocはヒープ(alloccaはスタック)領域が使われます.

youkun_1
質問者

補足

 ご回答ありがとうございます。メモリ2kというのは、ヒープ領域のことです。スタック領域は、700byte取って、上記プログラムを走らせました。

回答No.1

実際に見てみないので、予測の1つにしかならないですが、上記ソースを記述している関数の時点で、スタックがギリギリ、ということはないでしょうか? malloc関数はその内部でまたスタック領域を使用すると思いますが、それに耐えられないくらいの状態で、mallocが呼ばれてるとか。

youkun_1
質問者

補足

ご回答ありがとうございます。malloc関数の動作について、理解不足で、スタック領域を使用するということは考えていませんでした。  malloc関数は、どれくらいスタック領域を使用するのでしょうか? (確保する領域にもよるのでしょうか?)

関連するQ&A

専門家に質問してみよう