2012-03-15 15 views
11

以下のコードは、Windowsで実行するとアドレスを返しますが、NULLを返すと予想しています。Windowsでmalloc(0)がnull以外のアドレスを返すのはなぜですか?

int main() 
{ 
    char *ptr = NULL; 
    ptr = malloc(0); 
    printf("malloc returned = %u\n", ptr); 

} 

このようなmallocの実装を促すものはありますか?それの背後に何らかの理由がありますか?

これは0バイトのメモリなので、データの書き込みは試行しませんでした。しかし、この記憶は何のためにも使えますか? comp.lang.cよくある質問の中に答えています

答えて

9

を行うことができますと言います。そして、何の長さゼロのブロックは、Win32ヒープに存在しないので、次のことができます。

(運がよけれと新しいサイズが小さい場合)、ほとんどのヒープのブロックを再利用につながるはずです
void *p = malloc(0); 
// ... do some stuff in between... 
realloc(p, n); 

。マイナーな機会主義者の最適化(または文脈と血中のコーヒーのレベルに応じてスローダウン)。

これは簡単な例です。実際の状況は、バッファが作成されたときにバッファを割り当て、バッファを増やすこともできます。入力が制御するのが煩わしい場合は、バッファサイズをゼロにすることができます。

+0

+1私が実際に見たように、1人は、malloc'd/realloc'dメモリを非常に大きくする可能性のあるループ内の何かを特殊なケースに入れたくないときに、この "利点"にこれを使用します。 – JimR

+1

しかし、あなたは 'realloc'にヌルポインタを渡すことができます。だから、このトリックは決して必須ではありません。ちょうど同様に 'void * p = 0;'でも構いません。 –

+0

@スティーブそれは本当にトリックではありません。これは、プログラミングやルーズなプラットフォーム仕様の成果物です。テストがなければ、HeapRealloc(heap、HEAP_REALLOC_IN_PLACE_ONLY、0、4)がどのように動作するかは不明です。 – ActiveTrayPrntrTagDataStrDrvr

7

http://c-faq.com/ansi/malloc0.html

ANSI/ISO規格は、それがいずれかを実行することを言います。振る舞いは実装定義です(質問11.33参照)。移植可能なコードは、malloc(0)を呼び出さないように注意するか、ヌルリターンの可能性に備える必要があります。

+0

しかし、実装が有効な値を返すようにするにはどうすればよいでしょうか?すべてのケースでNULLを返すのは意味がありませんか? – Jay

+3

必ずしもそうではありません。コンパイラ作成者を第二に推測するのは嫌ですが、実装者は、メモリを本当に割り当てることができない場合にのみ、mallocに 'null 'を返すようにすることができます。 – CAbbott

+1

@ Jay:実装はどちらでも自由であるため、コードが少ない方を選択することもできます。 0の入力をテストしてヌルポインタを返すための余分なコード行を記述するのは難しいことではありません。そして、実装が既に必要なサイズが馬鹿馬鹿しくない(そしてもしあればヌルポインタを返す)というテストを既に持っているならば、それは馬鹿げて巨大な、またはゼロをチェックするのと同じように簡単かもしれません。 –

8

質問の2番目の部分に答えるには、「アクセス可能な部分」が返されたアドレスから始まる0バイトなので、メモリは何にも使用できません。

IIRCインプリメンテーションが非ヌルを返す場合は、他の現在割り当てられているメモリブロックの異なるアドレスになりますが、IIRCでも保証されます。理論的には、(ポインタ型の)一時的な一意のIDとしてアドレスを使用できますが、他にも一意のIDを取得する方法はたくさんあります。たとえそれを使用しようとしても、malloc(1)malloc(0)と同様に動作し、移植性が高くなります。

0

これは役に立たないわけではありません。 mallocから返されたブロックは一意であると予想されます。したがって、mallocによって返された各ブロックはブロック内のデータとそのアドレスであるブロックの固有の識別子の両方を持ちます。後者のプロパティが重要であり、データが含まれていないということは問題ではない場合は、便利です。

ただし、ポータブルでないコードを記述するための素晴らしい方法を述べました。しかし、これは違法コードと同じではありません。それは、実装がWindowsをサポートしているように完全に有効です(Windowsと同様)。

関連する問題