3
4

2 に答える 2

5

技術的には、この標準では、オブジェクトポインタの種類ごとに異なる表現(異なるサイズでも)を使用できますが、char*void*は同じ表現である必要があります。しかし、以下はUBです。

int *ip = 0;
free(*(void**)(&ip));

のメモリは、ipのメモリと同じサイズである必要はなくvoid*、タイプのnullポインタのビットパターンであっても、タイプのnullポインタのint*ビットパターンと同じである必要はありませんvoid*int*それらが異なる場合は、もちろん、コンパイラは、 tovoid*またはbackに変換するたびに、それらの間で変換するコードを挿入する必要があります。

実際には、実装はそれを行いません(たとえば、Posixはそれを禁止しています)。

char*ただし、さらに重要なのは、厳密なエイリアシングルールでは、型の左辺値を使用してオブジェクトにアクセスすることはできませんvoid*。したがって、実際には、ポインター表現に関する懸念はコードを破壊しませんが、オプティマイザーは実際に破壊する可能性があります。基本的に、関数呼び出しmyfree((void**)(&p))がインライン化されると、コンパイラーは次のことを確認できます。

char *p = <something>;
void **data = (void**)(&p);
free(*data);
*data = NULL;
// code that reads p

*data = NULLオプティマイザは、がタイプのオブジェクトを設定していることに注意することができますがvoid*、「pを読み取るコード」は、タイプのオブジェクトを読み取っていますchar*。これは、他のオブジェクトとのエイリアスが禁止されていvoid*ます。したがって、指示を並べ替えたり、*data = NULL;完全に削除したり、あるいは私が考えていなかった他のことを削除したりすると、1日が台無しになりますが、ルールに違反していなければ、コードが高速化されます。

于 2012-06-08T18:07:21.457 に答える
-1

You can use the MACRO to do this operation. This will be really great compare to having a function; I hope you know the advantage of using MACRO.

#define FREE_IF_NOT_NULL(x) if (x != NULL) { \
                                            free(x); \
                                            x = NULL; \
                                       }
于 2012-06-08T18:08:48.070 に答える