2016-09-10 7 views
0

は、私は今、tは*(Pool**)ans = NULL;が何をするのか理解しようとする時間を超える過ごしたこのスニペットここポインタをポインタにキャストしています...ポインタですか?

void* operator new(size_t nbytes) 
{ 
    if (nbytes == 0) 
    nbytes = 1;     // so all alloc's get a distinct address 
    void* ans = malloc(nbytes + 4); // overallocate by 4 bytes 
    *(Pool**)ans = NULL;    // use NULL in the global new 
    return (char*)ans + 4;   // don't let users see the Pool* 
} 

https://isocpp.org/wiki/faq/dtors

を見つけました。 ansは無効なポインタなので、Poolポインタにキャストされ、プールは0に設定されていると仮定します。ポインタは左に3番目の*のためポインタですがプール自体はありません。しかしプールにはoperator=が定義されていません。

pointer**は、明らかにポインタへのポインタです...しかし、この文脈では、これは意味がありません。ansは単一のポインタです。 「隠し」、4バイトのヘッダがPool(SO ansへのポインタであると考えPoolへのポインタへのポインタであることをおそらくため

答えて

4

ここPool**を使用する唯一の理由は、セマンティック正確であり、そして*(Pool **)ansを有しますタイプPool *)。

PoolNULLに割り当てることができない限り、*(Pool *)ans = NULLを実行できませんでした。これはおそらくここで意図した効果ではないでしょう。 *(int **)ans = NULLのようなもの、またはよりばかげた*(Pool ******)ans = NULLの場合は、最終的にはPoolへのポインタであることを意図している場合には、同じ結果が得られましたが、意味的に奇妙でしたでしょう。

+---+---+---+---+- - - 
| 0 | 0 | 0 | 0 | ... and nbytes more bytes 
+---+---+---+---+- - - 

^ ans   ^returned address (ans + 4) 

それらの最初の4つのバイトはどこかPoolへのポインタであることを意図している:あなたがになってしまいます一日の終わりに

void * ptr = malloc(sizeof(TYPE)); 
*(TYPE *)ptr = VALUE; 

意味を行う必要があります

これについて考える別の方法は、全体nbytesの事を無視し、この一般的なパターンを考慮することです。

void * ptr = malloc(sizeof(Pool *)); 
*(Pool **)ptr = NULL; 

そして、あなたのケースであなたはまだ、基本的にあなたがやっているの:TYPEはPool *であり、値がNULLであり、あなたがそのパターンにそれに合う場合さて、あなたはそれをすべてはまだ理にかなっているかを確認することができます最後にいくつかの余分なバイトを割り当てていますが、ここのタイプには関係ありません。

ここでは、sizeof(Pool *)ではなく、どこでも4をハードコードするために、ここでの問題(また意味的には怠惰)を求めている可能性があります。

2

いいえ、「プールポインタにキャスト」されていません。キャストは次のとおりです。

(Pool**) 

これはPoolへのポインタではありません。これはPoolへのポインタへのポインタです。

だから、ansPool **であるとふりをしてみましょう。その場合:

*ans = NULL; 

これは今NULLからansがへのポインタであるポインタを設定します。 Poolクラスの製造されたインスタンスではありません。しかしそれへのポインタ。

しかし、大きな問題はここにあります:

void* ans = malloc(nbytes + 4); // overallocate by 4 bytes 
*(Pool**)ans = NULL;    // use NULL in the global new 
return (char*)ans + 4;   // don't let users see the Pool* 

これは非常に古いコードであり、それは、ポインタが4バイト長である場合にのみ動作します。

最新の64ビットプラットフォームでは、8バイト長のポインタでは、この全部が悲惨に失敗します...

+0

「奇妙」ではありません。これは、オブジェクトへのすべてのポインタが4バイト(通常は32ビットとも呼ばれる)であり、関連するアラインメントであることを前提とするコードです。 '4 'はおそらく' sizeof(Pool *)'として書き直される方が良いでしょう。または完全に削除してください。オフセットは汚れたトリック(擬似安全対策を追加しようとしているプログラマー)のほうが多く、実際の使用量はそれほど多くありません。 (それを削除する場合は、 'Pool'を直接操作する他の関数も変更してください。オフセットも使用されます)。 – Peter

+0

@Peter Samは「ODD」ではなく「OLD」と入力しました。 –

関連する問題