50

mallocCプログラムで使用すると、次の警告が表示されます。

warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default]

それがなくても機能しますが、それから含める<malloc.h><stdlib.h>、削除することができます。warning

gccだから私は疑問に思っていました、これらのヘッダーと私が何も含まないときにリンクするヘッダーの違いは何ですか?

(私はで使用ubuntu 12.04 64-bitしていgcc 4.6.3ます)

4

6 に答える 6

58

<malloc.h>ヘッダーは非推奨になりました(そして、mallinfo(3)のような非標準関数を定義するLinux固有のものです)。単にmalloc(3)および関連する標準関数(たとえば、、、....)が必要な場合は、代わりに使用してください。これはC89(およびそれ以降)の標準で定義されていますが、<stdlib.h>freecallocrealloc<stdlib.h><malloc.h>

調べてみる/usr/include/malloc.hと、いくつかの非標準関数(malloc_stats(3)など)があります-に加えてmalloc...。

またgcc、ヘッダーファイルではなく、ライブラリをリンクします。詳細については、リンカーとローダーに関するLevineの本をお読みください。

ヘッダーを含めない場合(そして明示的にmalloc自分自身を宣言しない場合、これは悪い考えです)、malloc何らかの値を返すものとして暗黙的に宣言されintます(これは間違っています)。使用するときは、少なくとも-Wallフラグを渡すことをお勧めします。gcc

関係する実際のプログラムを理解するために渡すこともできます-v。コンパイラは適切であり(アセンブリコードを生成)、アセンブラ、リンカ、およびcollect2はリンカを呼び出す内部ユーティリティです。gcccc1asld

于 2012-10-19T11:31:53.707 に答える
12

stdlib.hは、特に、、関数を宣言する標準のCヘッダーmalloc()です。これは、含める必要のあるヘッダーです。calloc()free()

malloc.hは非標準のヘッダーであり、多くのシステムで見られ、そのプラットフォームで使用されるmalloc実装に固有の追加関数を定義することがよくあります。

これらのいずれも含めない場合、デフォルトはありませんがmalloc()、malloc関数を事前に宣言せずに呼び出すと、Cは関数プロトタイプがint malloc();であると見なします。これは多くの場合間違っています。ヘッダーに加えて、Cコンパイラは通常、mallocの実装が存在するLinux上のglibcなどの標準ライブラリにリンクします。

ヘッダーファイルとライブラリには違いがあることに注意してください。ヘッダーファイルは、構造体や関数プロトタイプなどを宣言します。ライブラリには、実装、コンパイルされたコードが含まれています。ライブラリにリンクし、#includeファイルをヘッダーします。

于 2012-10-19T11:34:49.983 に答える
6

ヘッダーは異なる関数のセットを宣言しますが、どちらも前方宣言しmallocます。

どちらも含めない場合は、のプロトタイプがないmallocため、警告が表示されます。ただし、関数は1つしかないため、同じ関数に対してリンクしmallocます。これは、2つの場所で前方宣言されています。前方宣言は、malloc関数とのリンクを支援するためのものではなく、コンパイラーが呼び出しの前後に正しいコードを発行し、引数を指定して戻り値を読み取ることができるようにするためのものです。

<malloc.h>これは標準のインクルードではないことに注意してください。GCCに含まれることはないと思いますが、それが必要な宣言を提供する1つの方法であるため、GCCがstdlib.h含まれるmalloc.h可能性があることを想像できます。

于 2012-10-19T11:31:26.910 に答える
4

<malloc.h>は標準のヘッダーではないため、移植性はありません。malloc()標準は他を置きます。で<stdlib.h>

于 2012-10-19T11:34:11.540 に答える
4

<malloc.h>と<stdlib.h>の違いについてはすでに説明している人もいます。

どちらも含まれていない場合の警告は、C関数のしくみの定義です。プロトタイプのない関数(独自に宣言せず、ヘッダーを含まない場合にある関数)は、int戻り型と未指定の引数リストを持つ関数として扱われます。

コンパイラーはデフォルトの昇格(例えば、float to doubleなど)を実行し、関数が呼び出されます。関数で使用される引数の数が渡された数と異なる場合、またはデフォルトの昇格後の引数のタイプが関数の実装と互換性がない場合、それは未定義の動作です。

ISO 9899:1999(C99)§6.5.2.2、¶6を参照してください:

呼び出された関数を表す式の型がプロトタイプを含まない場合、整数の昇格が各引数で実行され、型のある引数floatがに昇格されdoubleます。これらはデフォルトの引数プロモーションと呼ばれます。引数の数がパラメーターの数と等しくない場合、動作は定義されていません。関数がプロトタイプを含む型で定義されていて、プロトタイプが省略記号(、...)で終わっているか、昇格後の引数の型がパラメーターの型と互換性がない場合、動作は未定義です。関数がプロトタイプを含まない型で定義されており、昇格後の引数の型が昇格後のパラメーターの型と互換性がない場合、次の場合を除いて、動作は未定義です。

  • 1つのプロモート型は符号付き整数型であり、もう1つのプロモート型は対応する符号なし整数型であり、値は両方の型で表現可能です。
  • どちらのタイプも、文字タイプまたはの修飾バージョンまたは非修飾バージョンへのポインターvoidです。

プロトタイプなしで呼び出す場合malloc()、これは非常に悪い可能性があります。 引数をmalloc()受け入れ、ポインタを返します。整数引数のデフォルトの昇格の結果、サイズがとは異なる整数が生成される場合、未定義の動作が発生します。また、がと異なるサイズの場合(たとえば、64ビットシステムでは、多くの場合32ビットで64ビットになります)、返されるポインタは混乱します。size_tvoid *size_tintvoid *intvoid *

于 2016-02-12T23:04:45.777 に答える
1

違いを知るには、その内容を自分で読んでください。

デフォルトでは、gccはどちらも読み取りません。

それらを読むと、それらが異なって宣言していることがわかりますmalloc

于 2012-10-19T11:30:57.050 に答える