70

ダングリングポインタを比較することは合法ですか?

int *p, *q;
{
    int a;
    p = &a;
}
{
    int b;
    q = &b;
}
std::cout << (p == q) << '\n';

pとの両方qが既に消えたオブジェクトを指している点に注意してください。これは合法ですか?

4

3 に答える 3

57

はじめに:最初の問題は、 の値を使用することが合法かどうかですp

aが破棄された後、無効なポインタ値pと呼ばれるものを取得します。N4430からの引用(N4430 のステータスについては、以下の「注」を参照してください):

ストレージ領域の期間が終了すると、割り当て解除されたストレージの任意の部分のアドレスを表すすべてのポインターの値が無効なポインター値になります。

無効なポインター値が使用された場合の動作も、N4430 の同じセクションで説明されています (C++14 [basic.stc.dynamic.deallocation]/4 にはほぼ同じテキストが表示されます)。

無効なポインター値による間接化と、無効なポインター値を割り当て解除関数に渡すと、未定義の動作になります。無効なポインター値のその他の使用には、実装定義の動作があります。

[脚注:一部の実装では、無効なポインター値をコピーするとシステム生成のランタイム エラーが発生すると定義されている場合があります。— 脚注終了 ]

そのため、実装のドキュメントを調べて、ここで何が起こるかを調べる必要があります (C++14 以降)。

上記の引用符での使用という用語は、C++14 [conv.lval/2] のように、左辺値から右辺値への変換が必要であることを意味します。

左辺値から右辺値への変換が式 e に適用され、[...] glvalue が参照するオブジェクトに無効なポインター値が含まれている場合、動作は実装定義です。


履歴: C++11 では、これはimplementation-definedではなくundefinedと呼ばれていました。DR1438で変更されました。完全な引用については、この投稿の編集履歴を参照してください。


への適用p == q: C++14+N4430 で、評価の結果が実装定義であり、ハードウェア トラップが発生することを実装が定義していないことを受け入れたpqします。[expr.eq]/2 は次のように述べています。

2 つのポインターは、両方が null である場合、または両方が同じ関数を指している場合、または両方が同じアドレス (3.9.2) を表している場合は等しく、そうでない場合は等しくありません。

どの値がいつ取得され、評価されるかは実装定義pqあるため、ここで何が起こるかはわかりません。ただし、実装定義または未指定のいずれかでなければなりません。

この場合、g++ は特定されていない動作を示すようです。-Oスイッチに応じて、同じメモリアドレスが破棄された後に再利用されたかどうかに応じて、1または のいずれかを言うことができました。0ba


N4430 に関する注意:これは C++14 に対する提案された欠陥の解決策であり、まだ受け入れられていません。オブジェクトの有効期間、無効なポインター、サブオブジェクト、共用体、および配列境界アクセスに関連する多くの文言がクリーンアップされます。

C++14 のテキストでは、[basic.stc.dynamic.deallocation]/4 以降の段落で、を使用すると無効なポインター値が発生することが定義されていますdelete。ただし、同じ原則が静的ストレージまたは自動ストレージに適用されるかどうかは明確に述べられていません。

[basic.compound]/3 には「有効なポインター」という定義がありますが、意味を持って使用するにはあいまいすぎます。[basic.life]/5 (脚注) は同じテキストを参照して、これは、すべてのタイプのストレージに適用することを意図していたことを示唆しています。

N4430 では、すべての保存期間に明確に適用されるように、テキストはそのセクションから 1 レベル上に移動されます。添付のメモがあります:

起草注:これは、動的ストレージ期間だけでなく、終了できるすべてのストレージ期間に適用する必要があります。スレッドまたはセグメント化されたスタックをサポートする実装では、スレッドと自動ストレージは動的ストレージと同じように動作する場合があります。


私の意見:p無効なポインター値を取得すると言う以外に、標準 (N4430 より前) を解釈する一貫した方法はありません。この動作は、これまで見てきたセクション以外ではカバーされていないようです。したがって、この場合、N4430 の文言を標準の意図を表すものとして喜んで扱います。


于 2015-06-07T13:28:47.940 に答える