mallocの結果がゼロ?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
なみき

mallocの結果がゼロ?

#1

投稿記事 by なみき » 14年前

ルネサスのコンパイラでマイコンを開発してみようと、
プログラムを組んでみたのですが
思い通り動かないところがあります。

以下のコードがあります。

コード:

printf("buff_size: %d\n", buff_size);
printf("malloc(buff_size): %d\n", malloc(buff_size));
実行結果は
buff_size: 1024
malloc(buff_size): 0
となります。

mallocの値が0というのがよく判らないのですが、なんらかの理由で
ヒープ領域の確保に失敗したから0になったのでしょうか。
このような経験のある方はいらっしゃいませんか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: mallocの結果がゼロ?

#2

投稿記事 by softya(ソフト屋) » 14年前

OSが存在するのか?とかヒープ領域はC言語のライブラリでどう管理されているのか?とか確認されましたか?
OSが存在しない環境だとスタートアップルーチンで初期化しなければいけないとか、パソコン系C言語ではやらない事をしないと動きませんよ。

[追記]
開発環境やら詳細を明かしてもらえばこちらでも調べられます。
ルネサスのマイコンなんて少なくとも十種類ぐらいあるのでは?バリエーションを加えたらとんでもない数のはずです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 15年前

Re: mallocの結果がゼロ?

#3

投稿記事 by box » 14年前

なみき さんが書きました:

コード:

printf("malloc(buff_size): %d\n", malloc(buff_size));
詳しいことはよくわかりませんが、そもそも、
malloc()の結果を"%d"で出力することは正しいのでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: mallocの結果がゼロ?

#4

投稿記事 by softya(ソフト屋) » 14年前

box さんが書きました:
なみき さんが書きました:

コード:

printf("malloc(buff_size): %d\n", malloc(buff_size));
詳しいことはよくわかりませんが、そもそも、
malloc()の結果を"%d"で出力することは正しいのでしょうか。
正しいか正しく無いかと言えばC言語の規格としてみれば正しくないでしょうが、何らかの値が表示される可能性は非常に高いです。
ちなみに、%pにしたほうが良いと思われたのであればboxさんが、ちゃんと書いてあげてくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 15年前

Re: mallocの結果がゼロ?

#5

投稿記事 by box » 14年前

softya(ソフト屋) さんが書きました: %pにしたほうが良いと思われたのであればboxさんが、ちゃんと書いてあげてくださいね。
私は質問者さん自身に考えてほしいと思っています。
ちゃんと書くかどうかは、私の考えによります。
softyaさんの考えとは一致しないかもしれませんが、それはそれで仕方がないことです。

# ちゃんと書いてあげて、なんて言われたくなかった。なんかガッカリ。
最後に編集したユーザー box on 2011年8月05日(金) 22:42 [ 編集 3 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

なみき

Re: mallocの結果がゼロ?

#6

投稿記事 by なみき » 14年前

HEW SHコンパイラでOSはありません。 雑誌に付録としてついてきたsh7262です。
内容をお見せしたいのですが、ちょっと規模が大きくなっていて、
コードの抜粋が難しくなっています。

boxさんのおっしゃるとおり、(unsigned char *)malloc(buff_size) では
駄目かも知れません。
ためしにassertするとabort()に飛ばされてしまうので、
評価結果が偽(0)であることは間違いないようです。

ヒープ領域がちゃんと確保できなくて 0 になっているのだと仮定して
もう少しメモリ周りの設定を見直してみます。

たかぎ
記事: 328
登録日時: 15年前
住所: 大阪
連絡を取る:

Re: mallocの結果がゼロ?

#7

投稿記事 by たかぎ » 14年前

なみき さんが書きました:HEW SHコンパイラでOSはありません。
確か、sbrk関数を定義するなど、適切な設定が必要になるはずです。
そうしないと、ターゲットボードによってメモリマップが異なるので、ヒープをどのアドレスから何バイト割り当てるのか、処理系が知るすべがないからです。
いずれにせよ、まずはドキュメントを熟読することをお勧めします。
http://documentation.renesas.com/jpn/pr ... optimz.pdf

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: mallocの結果がゼロ?

#8

投稿記事 by softya(ソフト屋) » 14年前

高木さんの示された資料にヒープ領域の確保方法がかかれてますね。よく読んでみてください。
なみき さんが書きました:boxさんのおっしゃるとおり、(unsigned char *)malloc(buff_size) では
駄目かも知れません。
ためしにassertするとabort()に飛ばされてしまうので、
評価結果が偽(0)であることは間違いないようです。
あとboxさんの言いたかったことを推測で書くと、「整数型とポインタでは型が違うので、整数型の書式である%dで安易に代用できる思わないほうが良い」って事なのでは無いでしょうか。なみきさんにうまく伝わっているか心配だったので書かせて頂きました。
mallocの失敗した時の戻り値は、偽(0)でもなく数値0でもなくNULLと考えるのが正しいです。大半の処理系は0と同じですけどね。
なので
assert(malloc(buff_size)!=NULL);
が正しいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たかぎ
記事: 328
登録日時: 15年前
住所: 大阪
連絡を取る:

Re: mallocの結果がゼロ?

#9

投稿記事 by たかぎ » 14年前

softya(ソフト屋) さんが書きました:mallocの失敗した時の戻り値は、偽(0)でもなく数値0でもなくNULLと考えるのが正しいです。大半の処理系は0と同じですけどね。
SHだというのは後出しの情報ですからね...。
仮にH8とかだった場合、int型は16ビットですが、ポインタ型は32ビット、しかもビッグエンディアンです。
%dを使うと上位16ビットしか表示されませんから、もし下位16ビットが非ゼロだとしても、mallocの返却値がゼロだと誤認してしまいます。
未定義の動作に依存したプログラミングをしていることがそもそもの間違いですね。

なみき

Re: mallocの結果がゼロ?

#10

投稿記事 by なみき » 14年前

HEWにて初期設定のヒープサイズを0x400から0x800に拡張することで
解決しました(非ゼロの値が返ってきた、というだけで詳しくは検証していませんが・・・)。
たかぎさんのおっしゃることも分かりましたので、
double型やそれ以上のビットを扱う場合の検証に適当に%dを使うのはもう止めます。

で、これと関係あるかどうか不明ですが、次のような関数を
組み込んでみたところ、次のような関数でエラーが出てしまいました。

コード:

double nmea_atof(const char *str, int str_sz)
{
    char *tmp_ptr;
    char buff[NMEA_CONVSTR_BUF];
    double res = 0;

    if(str_sz < NMEA_CONVSTR_BUF)
    {
        memcpy(&buff[0], str, str_sz);
        buff[str_sz] = '\0';
	t_printf("buf:%s\n", &buff[0]); /* debug */
        res = strtod(&buff[0], &tmp_ptr); /* 怪しい */
	t_printf("res:%f\n", res); /* debug */
    }
    return res;
}
また定数は次のように定義されています。
#define NMEA_CONVSTR_BUF (256)

コンソールの表示結果は
buf:3349.896
res:%f

となりました。文字列変数bufは3349.896で意図した変数です。
strtod関数はコンパイラの通りですから、
浮動小数点resがちゃんと得られてもいい筈ですが・・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: mallocの結果がゼロ?

#11

投稿記事 by softya(ソフト屋) » 14年前

t_printfに%fが実装されていないのでは?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

なみき

Re: mallocの結果がゼロ?

#12

投稿記事 by なみき » 14年前

なるほど!その可能性がありますね。
言われて初めて気がつきました。

t_printfは簡易printf関数で、
これまでfloat型のコンソール表示に活用してきた関数です。
これがもしかしたらdoubleまで拡張されてない可能性もあります。
ソースを見せるのは簡単ですが、まずは自分で検証してみます。

なみき

Re: mallocの結果がゼロ?

#13

投稿記事 by なみき » 14年前

%fも解決しました。簡易printfが%fに対応できないことが分かったので、
sprintf()でdoubleをstringに変換して%sで表示できました。

課題は簡単に解決しましたが、本当は%fが扱えるprintfを自作するよう
努力するのが本筋かも知れませんけど・・・

でも第三者の視点がすごく参考になりました。振り返ると単純な
見落としばかりだったように思います。
softyaさんをはじめ、皆さんお世話になりました。

閉鎖

“C言語何でも質問掲示板” へ戻る