電子書籍の厳選無料作品が豊富!

 組み込み系のプログラミングをやっているもので、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関数等を自作とかされていますでしょうか?

 どうぞよろしくお願い致します。

A 回答 (4件)

ルネサスのCコンパイラといっても、SHとH8とM16Cでは事情が違う気がしますが...



ヒープ領域の使用状況をよく調べてみてください。
sbrkが呼び出されるたびに、呼出元(malloc, calloc, reallocの呼出元)を調べた方がよいでしょう。

例えば、ストリームの内部でもバッファリング用のメモリが割付けられるので、それがヒープを食いつぶしている可能性があります。
BUFSIZが512だとすれば、管理領域の4バイトを加えて、1ストリームあたり516バイト消費します。標準入力、標準出力、標準エラーの三つがスタートアップでオープンされるのであれば、516 × 3 = 1548となり、残りは500バイト。
100バイトを4回割付ければ416バイト必要なので、残りは84バイト。そして、5回目の割付けでしくじります。このとき、sbrkの定義が適切でなければ、何が起きても不思議ではありません。
    • good
    • 0
この回答へのお礼

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

 どうもありがとうございました。




 

お礼日時:2008/08/25 23:04

「組込み系」というだけでは正確なことは何も分かりません。


処理系を具体的に補足してください。単なるコンパイラの製品名ではなく、ターゲットに合わせてmallocをカスタマイズする部分(例えばsbrkの自作など)があるはずですので、その内容についても合わせて補足してください。

なお、組込み系の多くは、「フリースタンディング環境」に分類されます。フリースタンディング環境では、規格上mallocは提供されませんので処理系の独自拡張になります。

この回答への補足

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

補足日時:2008/08/24 22:50
    • good
    • 0

if(( p1 = malloc(100)==NULL) break;


のようにして,まずはプログラムミス(mallocの失敗の可能性に対応していない)なのか,他の要因なのかをまず見分けるべきでしょう.

余談ですが,mallocに(char*) はいりません.

それと,メモリを2k確保と行っても,ヒープとスタックとがありますが,どっちにどれだけ割り当てているかわかりますか?
通常,mallocはヒープ(alloccaはスタック)領域が使われます.

この回答への補足

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

補足日時:2008/08/24 22:40
    • good
    • 0

実際に見てみないので、予測の1つにしかならないですが、上記ソースを記述している関数の時点で、スタックがギリギリ、ということはないでしょうか?


malloc関数はその内部でまたスタック領域を使用すると思いますが、それに耐えられないくらいの状態で、mallocが呼ばれてるとか。

この回答への補足

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

補足日時:2008/08/24 22:34
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!