GNU/Linux >> Linux の 問題 >  >> Linux

malloc(0) は何を返しますか?

他の人は malloc(0) と答えました 動作します。あなたが尋ねた、まだ答えられていない質問の1つに答えます(と思います)。質問は realloc(malloc(0), 0) についてです :

<ブロック引用>

malloc(0) とは 戻る? realloc(malloc(0),0) の答えは同じでしょうか? ?

標準は realloc(ptr, size) についてこう言っています :

  • if ptr NULL です 、 malloc(size) のように動作します 、
  • それ以外 (ptr NULL ではありません )、ptr までに古いオブジェクト ポインターの割り当てを解除します。 新しく割り当てられたバッファへのポインタを返します。 size の場合 が 0 の場合、C89 は効果が free(ptr) と同等であると述べています。 .興味深いことに、C99 ドラフト (n1256 または n1336) でそのステートメントを見つけることができません。 C89 では、その場合に返される適切な値は NULL だけです。 .

したがって、2 つのケースがあります:

  • malloc(0) NULL を返します 実装について。次に、あなたの realloc() 呼び出しは realloc(NULL, 0) と同等です .これは malloc(0) に相当します 上から (そしてそれは NULL この場合)
  • malloc(0) NULL 以外を返します .次に、呼び出しは free(malloc(0)) と同等です .この場合、malloc(0)realloc(malloc(0), 0) ではない

ここで興味深いケースがあることに注意してください:2 番目のケースでは、malloc(0) の場合です。 NULL 以外を返します 成功した場合でも、NULL を返すことがあります。 失敗を示します。これは次のような呼び出しになります:realloc(NULL, 0) 、これは malloc(0) と同等です NULL を返す場合と返さない場合があります .

C99 での省略が見落としなのか、それとも C99 で realloc(ptr, 0) という意味なのかはわかりません。 NULL 以外の場合 ptr free(ptr) と同等ではありません . gcc -std=c99 でこれを試しました 、および上記は free(ptr) と同等です .

編集 :私はあなたの混乱が何であるかを理解していると思います:

コード例のスニペットを見てみましょう:

ptr = malloc(0);
if (ptr == realloc(ptr, 1024))

上記は malloc(0) == realloc(malloc(0), 1024) と同じではありません . 2 番目の malloc() 呼び出しは 2 回行われますが、最初の呼び出しでは、以前に割り当てられたポインターを realloc() に渡しています。 .

最初のコードを最初に分析しましょう。 malloc(0) と仮定すると NULL を返さない 成功時、ptr 有効な値があります。 realloc(ptr, 1024) を実行すると 、 realloc() 基本的に、サイズが 1024 で ptr の新しいバッファが提供されます。 無効になります。適合する実装は、既に ptr にあるものと同じアドレスを返す場合があります .だから、あなたの if 条件は true を返す場合があります。 (ただし、ptr の値を見てください。 realloc(ptr, 1024)の後 未定義の動作である可能性があります。)

今あなたが尋ねる質問:malloc(0) == realloc(malloc(0), 1024) .この場合、両方の malloc(0) LHS と RHS では NULL 以外を返します .次に、それらは異なることが保証されます。また、malloc() からの戻り値 LHS は free() ではありません d まだ、その他の malloc()calloc() 、または realloc() その値を返さない場合があります。つまり、条件を次のように記述した場合:

if (malloc(0) == realloc(malloc(0), 1024)
    puts("possible");

possible は表示されません 出力 (malloc() の両方を除く) および realloc() 失敗して NULL を返します ).

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    void *p1;
    void *p2;

    p1 = malloc(0);
    p2 = realloc(p1, 1024);
    if (p1 == p2)
        puts("possible, OK");

    /* Ignore the memory leaks */
    if (malloc(0) == realloc(malloc(0), 1024))
        puts("shouldn't happen, something is wrong");
    return 0;
}

OS X では、コードを実行しても何も出力されませんでした。 Linux では、possible, OK を出力します。 .


malloc(0) 実装が定義されています C99に関する限り。

C99 から [セクション 7.20.3]

<ブロック引用>

calloc、malloc、および realloc 関数の連続呼び出しによって割り当てられるストレージの順序と連続性は規定されていません .割り当てが成功した場合に返されるポインターは、任意の型のオブジェクトへのポインターに割り当てられるように適切に配置され、割り当てられた空間内のそのようなオブジェクトまたはそのようなオブジェクトの配列にアクセスするために使用されます (空間が明示的に割り当て解除されるまで)。割り当てられたオブジェクトの有効期間は、割り当てから解放までです。そのような各割り当ては、他のオブジェクトから切り離されたオブジェクトへのポインタを生成します。返されるポインターは、割り当てられたスペースの開始 (最下位バイトアドレス) を指します。スペースを割り当てることができない場合は、ヌル ポインターが返されます。 要求されたスペースのサイズがゼロの場合、動作は実装定義です :null ポインターが返されるか、返されたポインターがオブジェクトへのアクセスに使用されないことを除いて、サイズがゼロ以外の値であるかのように動作します。


C89 では、malloc(0) は実装依存です。C99 でこれが修正されたかどうかはわかりません。 C++ では、以下を使用:

char * p = new char[0];

明確に定義されています-有効な非nullポインターを取得します。もちろん、ポインターを使用して、未定義の動作を呼び出さずにポインターが指すものにアクセスすることはできません。

これが存在する理由については、一部のアルゴリズムにとって便利であり、ゼロ値のテストでコードを散らかす必要がないことを意味します。


Linux
  1. 「–」(二点鎖線)とはどういう意味ですか?

  2. 何をしますか?

  3. Exec 3とは何ですか?

  1. Bamfdaemonは何をしますか?

  2. poll() はタイムアウト 0 で何をしますか?

  3. 「cd -」は何の略ですか?

  1. セグメンテーション違反を起こしたプロセスが返すエラー コードは何ですか?

  2. kill -- -0 は何をしますか?

  3. CAP_NET_RAW は何をしますか?