web-dev-qa-db-ja.com

ptrがNULLであるfree(ptr)はメモリを破損しますか?

理論的には

free(ptr);
free(ptr); 

すでに解放されているメモリを解放しているため、メモリが破損しています。

しかし、どうすれば

free(ptr);
ptr=NULL;
free(ptr); 

OSは未定義の方法で動作するので、何が起こっているのかについて実際の理論的分析を得ることができません。私が何をしていても、このメモリ破損はありますか?

NULLポインターの解放は有効ですか?

103
Vijay

7.20.3.2 free関数

あらすじ

_#include <stdlib.h> 
void free(void *ptr); 
_

説明

free関数は、ptrが指すスペースの割り当てを解除します。つまり、さらなる割り当てに使用できるようにします。 ptrがNULLポインターの場合、アクションは発生しません。

ISO-IEC 9899 を参照してください。

そうは言っても、野生のさまざまなコードベースを見ると、人々が時々そうすることに気付くでしょう。

_if (ptr)
  free(ptr);
_

これは、NULLポインターを解放すると、一部のCランタイム(PalmOSの場合は確かにそうだったことを覚えています)がクラッシュするためです。

しかし、最近では、free(NULL)が標準で指示されているようにnopであると仮定するのが安全だと思います。

210
Gregory Pakosz

Cライブラリの標準準拠バージョンはすべて、free(NULL)をノーオペレーションとして扱います。

とはいえ、かつてfree(NULL)でクラッシュするfreeのバージョンがいくつかあったため、いくつかの防御的なプログラミング手法が推奨されることがあります。

if (ptr != NULL)
    free(ptr);
20

PtrがNULLの場合、操作は実行されません。

ドキュメントを言う。

free(NULL)がクラッシュしたPalmOSで作業したことを覚えています。

10
jlru

推奨される使用法:

_free(ptr);
ptr = NULL;
_

見る:

_man free

     The free() function deallocates the memory allocation pointed to by ptr.
     If ptr is a NULL pointer, no operation is performed.
_

free()の後にNULLにポインターを設定すると、その上でfree()を再度呼び出すことができ、操作は実行されません。

9
stefanB
free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */

NULLポインターを安全に削除できます。その場合、操作は実行されません。つまり、free()はNULLポインターに対して何もしません。

8
Prasoon Saurav

free(NULL)はCでは完全に正当であり、delete (void *)0およびdelete[] (void *)0はC++では正当です。

ところで、メモリを2回解放すると、通常、何らかのランタイムエラーが発生するため、何も破損しません。

6
n0rd

free(ptr)は、ptrがNULLの場合、Cに保存されますが、ほとんどの人が知らないのは、NULLが0に等しい必要はないということです。 IOポートです。このポートにアクセスするCでプログラムを作成した場合、値が0のポインターが必要になります。対応するcライブラリは、0とNULLを区別する必要があります。

敬具

3
andi8086

メモリの破損ではありませんが、動作は実装に依存します。標準では、合法的なコードである必要があります。

0