- ベストアンサー
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関数等を自作とかされていますでしょうか? どうぞよろしくお願い致します。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
ルネサスのCコンパイラといっても、SHとH8とM16Cでは事情が違う気がしますが... ヒープ領域の使用状況をよく調べてみてください。 sbrkが呼び出されるたびに、呼出元(malloc, calloc, reallocの呼出元)を調べた方がよいでしょう。 例えば、ストリームの内部でもバッファリング用のメモリが割付けられるので、それがヒープを食いつぶしている可能性があります。 BUFSIZが512だとすれば、管理領域の4バイトを加えて、1ストリームあたり516バイト消費します。標準入力、標準出力、標準エラーの三つがスタートアップでオープンされるのであれば、516 × 3 = 1548となり、残りは500バイト。 100バイトを4回割付ければ416バイト必要なので、残りは84バイト。そして、5回目の割付けでしくじります。このとき、sbrkの定義が適切でなければ、何が起きても不思議ではありません。
その他の回答 (3)
- jacta
- ベストアンサー率26% (845/3158)
「組込み系」というだけでは正確なことは何も分かりません。 処理系を具体的に補足してください。単なるコンパイラの製品名ではなく、ターゲットに合わせてmallocをカスタマイズする部分(例えばsbrkの自作など)があるはずですので、その内容についても合わせて補足してください。 なお、組込み系の多くは、「フリースタンディング環境」に分類されます。フリースタンディング環境では、規格上mallocは提供されませんので処理系の独自拡張になります。
補足
ご回答ありがとうございます。コンパイラは、ルネサスのCコンパイラです。sbrkは提供されているものを使用していて、カスタイマイズしていません。またリアルタイムOSは、のせていません。 抽象的で申し訳ございませんが、質問に書いてあるプログラムくらいのものであれば、カスタマイズすることなく動作すると思っていました。 やはりスタックの問題でしょうか?
- a-saitoh
- ベストアンサー率30% (524/1722)
if(( p1 = malloc(100)==NULL) break; のようにして,まずはプログラムミス(mallocの失敗の可能性に対応していない)なのか,他の要因なのかをまず見分けるべきでしょう. 余談ですが,mallocに(char*) はいりません. それと,メモリを2k確保と行っても,ヒープとスタックとがありますが,どっちにどれだけ割り当てているかわかりますか? 通常,mallocはヒープ(alloccaはスタック)領域が使われます.
補足
ご回答ありがとうございます。メモリ2kというのは、ヒープ領域のことです。スタック領域は、700byte取って、上記プログラムを走らせました。
- alesi_sato
- ベストアンサー率35% (23/65)
実際に見てみないので、予測の1つにしかならないですが、上記ソースを記述している関数の時点で、スタックがギリギリ、ということはないでしょうか? malloc関数はその内部でまたスタック領域を使用すると思いますが、それに耐えられないくらいの状態で、mallocが呼ばれてるとか。
補足
ご回答ありがとうございます。malloc関数の動作について、理解不足で、スタック領域を使用するということは考えていませんでした。 malloc関数は、どれくらいスタック領域を使用するのでしょうか? (確保する領域にもよるのでしょうか?)
お礼
ご回答ありがとうございます。質問に書いてあるプログラムが途中で止まる件は、解決しました。 stdlib.hをインクルードしていないという凡ミスでした。大変ご迷惑おかけいたしました。 しかしながら、本来のプログラムは相変わらず動作しません。 質問に書いたmalloc、free関数の中でループしている現象ではなく、sbrkで領域が確保できずエラーになってしまいます。 メモリーリークしているようなので、後は、回答者様のご意見を参考に、プログラムをもう一度見直してみます。 どうもありがとうございました。