25

次のようなコードに出くわしました:

/* Allocate memory for _ptr */

if(*((void **) &(_ptr)) != (void *) NULL)
{
   /* free _ptr */
}

以下と何が違うの?

/* Allocate memory for _ptr */

if (_ptr != NULL )
{
   /* free _ptr */
}

編集: _ptr は任意のタイプである可能性があります。実際には、これは次のようなマクロです。

#define RETURN_MEM_CHK(_ptr)   \
    {if(*((void **) &(_ptr)) != (void *) NULL){/* free _ptr */}

混乱を招いてすみません。

4

6 に答える 6

12

それが異なる結果をもたらす可能性がある1つの例(そして、私の特定のシステムで試してみたとき):

int _ptr = 0;
int whatever = 17;

if (*((void **) &(_ptr)) != (void *) NULL) {
    printf("Not equal (1)\n");
}

if (_ptr != NULL) {
    printf("Not equal (2)\n");
}

最初のバージョンは、整数変数_ptrが void ポインターであるかのように装い、void ポインターであるかのようにそのメモリにアクセスします。int が 32 ビットでポインターが 64 ビットの私のコンピューターでは、これは変数の外部でメモリを読み取ることを意味します。もちろん、これは未定義の動作であり、この場合、条件が true と評価されました。

_ptrがvoid*以外の型のポインターである場合、そのポインター型のサイズが異なるか、void ポインターとは異なる方法で表現されるシステムでは、同様の結果が得られます。

于 2013-06-04T10:17:58.010 に答える
6

さて、どのような違いがあるかは、の種類によって異なり_ptrます。

if (_ptr != NULL )

がポインター型でない場合_ptrは機能しません (およびNULLは へのキャストを含む null ポインター定数であり、がポインター型を持たなくても、値が 0 の単なる整数定数であればvoid*機能します)。NULL_ptr

_ptrポインタ型の場合はヌルポインタif (_ptr != NULL )と比較_ptrします。シンプル。

if(*((void **) &(_ptr)) != (void *) NULL)

未定義の動作を呼び出さない場合はsizeof (void*)、 address で始まるバイト&_ptrを a としてvoid*解釈し、その再解釈の結果を type の null ポインターと比較しますvoid*

_ptrがとは異なる表現を持つポインター型の値である場合、異なる動作をする可能性がありますvoid*

_ptrポインタ型でない場合に機能します。

ただし、すべての合理的な状況では、より複雑な言い方になります。

if ((void*)_ptr != NULL)
于 2013-06-04T10:13:47.980 に答える