次のコードがあるとします。
int *a = NULL;
a = calloc(1, sizeof(*a));
printf("%d\n", a);
a = realloc(a, 0);
printf("%d\n", a);
return (0);
戻り値:
4078904
0
この realloc は free と同等ですか?
注: WindowsXP で MinGW を使用しています。
free
これは、ポインターを呼び出すことと同等である場合とそうでない場合があります。結果は実装定義です。
C99標準(§7.20.3/ 1)から:
要求されたスペースのサイズがゼロの場合、動作は実装定義です。nullポインターが返されるか、返されたポインターがオブジェクトへのアクセスに使用されないことを除いて、サイズがゼロ以外の値であるかのように動作します。 。
これは、を含むすべてのメモリ管理機能に適用されますrealloc
。
必ずしも。
多くの場合、munissor が投稿したリンクと同じように動作しますが、Mac OS 10.5 のマニュアル ページには次のように記載されています。
size がゼロで ptr が NULL でない場合、新しい最小サイズのオブジェクトが割り当てられ、元のオブジェクトは解放されます。
「最小サイズのオブジェクト」とは何ですか? まあ、アロケータは割り当てに関するいくつかの情報を保存し、それはユーザーのために予約されたスペースに加えてしばしば割り当てられるスペースを必要とします。おそらく、「最小サイズのオブジェクト」は、これらのヘッダーの 1 つに加えて、ユーザー用に予約された 0 バイトのスペースです。
この規定は、標準化の時点で存在していた実装をサポートするために存在し、それらの実装は割り当て動作のデバッグに役立つと思います。
ジョナサンのコメントに対処するには
の違いを考えてみましょう
for (int i=0; i<VERY_BIG_NUMBER; ++i){
char *p = malloc(sizeof(char[10]));
free(p);
}
と
for (int i=0; i<VERY_BIG_NUMBER; ++i){
char *p = malloc(sizeof(char[10]));
realloc(p,0);
}
の適切な実装によりmalloc
、free
最初のクリップは際限なくメモリを消費しません。しかし、realloc
実装がそれらの「最小サイズのオブジェクト」を返す場合、そうなる可能性があります。
確かに、この例は不自然であり、「最小サイズのオブジェクト」が何を意味するかを理解することに依存していますが、テキストはそれを可能にしていると思います.
要するに、あなたが言う free
べきならfree
.
C99 標準 §7.20.3.4 (realloc) は次のように述べています。
realloc 関数は、ptr が指す古いオブジェクトの割り当てを解除し、size で指定されたサイズを持つ新しいオブジェクトへのポインターを返します。新しいオブジェクトの内容は、新しいサイズと古いサイズの小さい方まで、割り当て解除前の古いオブジェクトの内容と同じでなければなりません。古いオブジェクトのサイズを超える新しいオブジェクトのバイトの値は不定です。
ptr がヌル ポインターの場合、realloc 関数は、指定されたサイズに対して malloc 関数のように動作します。それ以外の場合、ptr が calloc、malloc、または realloc 関数によって以前に返されたポインターと一致しない場合、または空間が free または realloc 関数の呼び出しによって解放された場合、動作は未定義です。新しいオブジェクトのメモリを割り当てることができない場合、古いオブジェクトは割り当て解除されず、その値は変更されません。
これは、古いオブジェクトが割り当て解除 (解放) されたことを明確に示しています。戻り値は null ポインターである場合もあれば、§7.20.3 の一般的な注意事項で指定されている値である場合もあります。
要求されたスペースのサイズがゼロの場合、動作は実装によって定義されます。null ポインターが返されるか、サイズがゼロ以外の値であるかのように動作します。ただし、返されたポインターはオブジェクトへのアクセスには使用されません。
いずれにせよ、返された値を逆参照することはできません: への引数として使用することもfree()
、他の関数が参照しない限り、他の関数に渡すこともできます。