4

重複の可能性:
ポインタが配列内を指しているかどうかを確認する

配列とサイズがあり、特定のポインターが配列内の要素を指しているかどうかを確認したい場合、UBを呼び出さずに標準のCまたはC ++でこれを行う方法はありますか?

これは機能しますか?

bool is_inside(someType * array, int size, someType * other_pointer){
    for (int i = 0; i < size; i++)
        if (array + i == other_pointer)
            return true;
    return false;
}

編集:UBなしで同じ配列を指していないポインター以外の比較は使用できないことを理解しています==!=実際には期待どおりに機能しますが)。私はこれで間違っていましたか?

4

4 に答える 4

3

それはあなたがUBによって何を意味するかによります。

具体的には、ポインタの比較については、C++標準のセクション5.9「関係演算子」に次のように記載されています。

同じ型の2つのポインターpとqが、同じオブジェクトまたは異なる関数のメンバーではない異なるオブジェクトを指している場合、またはそれらの1つだけがnullである場合、、、およびの結果p<qは指定p>qされません。p<=qp>=q

定義(つまりtrue、_ false_コンパイラまたは結果のプログラムは、何でも実行できます)。

ただし、これまでのところ、Kirillのようなコードで期待どおりの動作を行わなかった実装ファミリは1つしか見ていません。

bool inside = (other_pointer >= array) && (other_pointer < array+size);

これらの実装は、アドレスに段落とオフセット部分があるMS-DOSリアルモードプログラムを構築することを目的としたコンパイラです。アドレスFF00:0010とFF01:0000は同じメモリ位置を指していますが、正しく思い出せば、一部のメモリモデル(確かに巨大なモデルですが、おそらく他のモデル)をコンパイルする場合を除いて、コンパイラが期待どおりに動作することは保証されませんでし

ただし、既存のオブジェクトを指しているか、p指しqていなかった場合(たとえば、ポインタが解放されたため)、何をしても動作は未定義になります。したがって、この種のメソッドを使用して、ポインターがまだ有効かどうかを判断することはできません。

于 2012-06-22T22:35:38.380 に答える
2

配列はメモリ内で連続していることが保証されているため、ポインタが最初の要素と最後の要素のアドレスの範囲内にあることを確認してください。

于 2012-06-22T22:19:47.343 に答える
0

ソリューションは機能しますが、不要なループが含まれているため最適ではありません。

あなたがすべきことは、配列へのポインタ、バイト単位の配列サイズを取り、ポイントされたアドレスがその配列によって占められているアドレス空間内にあるかどうかをチェックすることです。

于 2012-06-22T22:19:56.387 に答える
0

あなたは単に書くことができます:

bool inside = (other_pointer >= array) && (other_pointer < array+size);

これは法的なチェックです。

于 2012-06-22T22:20:51.600 に答える