2

malloc()現在、Visual C++ はで装飾されたランタイムに同梱されています__declspec( restrict )

MSDN によると、この装飾は、返されたポインターはmalloc()他のポインターによってエイリアスできないことをコンパイラーに示しています。malloc()わかりました、実際に異なるポインターを返すための 2 つの後続の呼び出し。でも電話したらどうなるの

void* memory1 = malloc( 10 );
free( memory1 );
void* memory2 = malloc( 10 );
//here memory1 may be equal to memory2

この場合、2 つのポインターはまったく同じ場所を指すことができます。これは、 の他のポインターの意味によってエイリアスを作成できないこととどのように相関し__declspec( restrict )ますか?

4

2 に答える 2

4

いったん free(memory1) すると、memory1 ポインターを介して何かにアクセスすることは未定義の動作 (鼻の悪魔など) になるため、コンパイラーは、malloc() 呼び出しの後に、memory2 が他のポインターによってエイリアス化されていないと仮定して最適化できます。

これが重要な理由については、コンパイラ自体が malloc() のセマンティクスに関する内部情報を持っていないと仮定すると、つまり他の関数と同じように扱うと仮定すると、返されたポインタが他のポインタによってエイリアス化されていないと仮定することはできません。(__declspec(restrict)または同等に__attribute__((malloc))、GCC では) は、ポインターが他のポインターによってエイリアス化されていないことをコンパイラーに伝えます。これにより、他の方法では不可能な最適化が可能になります。

于 2011-09-23T09:05:46.677 に答える
3

標準では、「オブジェクトの有効期間」について次のように述べています (N3290 の§3.8)。

型 T のオブジェクトの存続期間は、次の場合に終了します。
— T が非自明なデストラクタ (12.4) を持つクラス型である場合、デストラクタ呼び出しが開始される、または
— オブジェクトが占有するストレージが再利用または解放される。

freeが指すブロックを 'd' した後memory1、そのオブジェクトは死んでいます。それは存在しなくなりました。そのポインターを逆参照すると、未定義の動作になります。

memory2同じメモリアドレスを割り当てることができますが、何も「エイリアス」しません。その場所にあったものはなくなりました。

于 2011-09-23T09:23:05.707 に答える