malloc(0) の動作は処理系依存であり、NULL を返すかユニークなポインタを返すかのいずれかになる (ISO/IEC 9899:1990 7.10.3)。処理系に依存するため、特定の動作を期待したプログラムは書かない方が良いだろう。
ちなみに、malloc(0) がユニークなポインタを返す場合は、malloc() がふつうに返すポインタと同じで、malloc() が管理する領域に "少なくとも 0 バイト" の領域を作ってその先頭のアドレスを返すだけである。NULL を返さない理由としては、
という一連の処理で、n が 0 か 1 以上かで場合分けしなくてすむようになるから、というのが考えられる。
問題ない。
malloc() で割り付けた領域は、不要になった時点で free() すべきである。しかし、プログラムの終了時の free() は有害無益であり、それを理解しようとせずに短絡的に malloc() したものは free() する、という表面的な規範に従って満足しているアンチプロフェッショナルな態度は鬱陶しいとも言える。
malloc() で割付けた領域を OS に返すことについては、ISO/IEC 9899 や JIS X 3010 などの C 言語規格では一切述べていない。それどころか、malloc() で割付けた領域を解放しなければならないとも規定していない。
malloc() で割付けた領域を解放しなければならないと規定されていないので、解放せずに終了するプログラムでも strictly conforming program といえる。
conforming hosted implemetation は、すべての strictly conforming program を受け付けなければならないので、malloc() で割付けた領域を解放せずに終了するプログラムも受け付けなければならない。
さらに言えば、conforming hosted implementation は strictly conforming program を何回実行しようとも、ダウンしたり動作が不安定になったりしないものである、という仮定は合理的な仮定であると考えられる。
受け付けた結果、プログラム終了後に何が起こるかは規格の範疇外であり、その実装の環境 (OS など) で規定されるべきことである。例えば、malloc() したメモリーを free() せずに終了した場合、
逆に、例えば Windows の Win16 API で GlobalAlloc/GlobalFree を使い、GlobalFree を呼び忘れた場合はメモリーリークとなるが、これは malloc()/free() とは別の話である。
また、malloc() 相当のものが共有メモリーの割り当てと等価になっている OS があるそうで、この環境で free() 相当の関数を呼び忘れるとメモリーリークを起こす可能性はある。ただし、用意されている関数が malloc()/free() である可能性は低い。
さらに、組み込み用の OS では "ヒープの管理は全部アプリケーション側でやってね" と言うスタンスのものが少なくないそうだ。この環境で free() 相当の関数を呼び忘れるとメモリーリークが起きるだろうが、これも用意されている関数は malloc()/free() である可能性は低いと思われる。たとえ、malloc()/free() であっても、ANSI C 仕様に準拠している可能性はなさそうだ。
なお、Windows のリソ−スリークの話は、メモリーリークとは関係ない。たとえ、malloc() したメモリーを全て free() しても、リソースリークは起こりえる。
そのような決まりはない。そういう C コンパイラが多いだけである。
規格では、
6.1.2.4 Storage durations of objects [...] An object [...] has automatic storage durations. Storage is guaranteed to be reserved for a new instanace of such an object on each entry into the block with which it is associated, or on a jump from outside the block to a labeled statement in the block or in an enclosed block. [...] Storage for the object is no longer guaranteed to be reserved when execution of the block end in any way. (Entering an enclosed block suspends but does not end execution of the enclosing block. Calling a function suspends but does not end execution of the block containing the call.) [...] JIS X3010 6.1.2.4 オブジェクトの記憶域期間 無結合を持ち、かつ記憶域クラスstaticをもたずに宣言された識別子の オブジェクトは、自動記憶域期間(automatic storage duration)をもつ。 それが宣言されているブロックへ正常に入るごとに、又は外側の ブロックからそのブロック若しくはそのブロックの内側のブロックの中の 名札付き文へ分岐するごとに、自動記憶域期間をもつオブジェクトの 新しい出現のために記憶域を確保することを保証する。
以上、スタックという語は全く出てこない。