2016-10-30 6 views
0

したがって、配列Aの要素へのポインタを返す関数があります。そのポインタをパラメータとして受け取る別の関数があります。しかし、完全に任意のポインタを渡す可能性に対処するためには、関数が必要です。ポインタが指定された配列を指しているかどうかを確認します

ポインタが構造内のどこかを指しているかどうかを検出できる方法はありますか?この場合、私の配列は?

私は§6.5.8関係演算子はセクションではC.

+0

恐らく別の質問があります。ソレア。標準では、それが動作します言いませんが、あなたは、配列の開始を知っていれば与えられたポインタが間に入る場合、要素の数と各要素の大きさだけでなく、あなたが与えられているポインタは、あなたが言うことができます配列の始まりと終わり。問題は、ポインタが範囲外であれば、比較は標準で動作することが保証されていないことですが、最近ではほとんどの場合、セグメント化されていないマシン(ほとんどの場合)では実際に動作します。 –

+0

配列を扱っている場合は、オフセットを受け取らないのはなぜですか?つまり、インデックスとして使用される単純な整数です。そうすることで、あなたは所属のチェックを保存します。 –

答えて

3

唯一の移植可能な方法は、ポインタの可能なすべての有効値に対して等価性テストを使用することです。例えば、2つのポインタが実際に同一の配列(またはエンド過去1)の要素にポイントを実行しない限り、二つのポインタと、リレーショナル演算子(例えば<)を使用して、または減算する未定義の動作であることを

int A[10]; 

bool points_to_A(int *ptr) 
{ 
    for (int i = 0; i < 10; ++i) 
     if (ptr == &A[i]) 
      return true; 

    return false; 
} 

注。

+0

賢い!それは警告を取り除きます – Bob

+0

'int配列[100000];' ...ああ!しかし、それは標準が働くと言っているものです。 –

+0

また、両方のポインタが同じ配列から来ない限り、またはC++でない限り、ポインタを減算すると(例えば 'ptr -A')、未定義の振る舞いも生じると言うことは価値があります。 –

1

でのC++に関する同様の質問を見て、ではなくてきた、C11規格(ISO/IEC 9899:2011)は言う:

2つのポインタを比較すると、その結果は、指し示されたオブジェクトのアドレス空間内の相対的な位置に依存します。オブジェクト型に対する2つのポインタの両方が同じオブジェクトを指しているか、または両方が同じ配列オブジェクトの最後の要素を指している場合、それらは等しいと比較されます。指し示されたオブジェクトが同じ集約オブジェクトのメンバである場合、後で宣言された構造体メンバへのポインタは、構造体の前に宣言されたメンバへのポインタよりも大きく、添字値が大きい配列要素へのポインタは、添字の値は低くなります。同じユニオンオブジェクトのメンバーへのすべてのポインタが等しいと比較されます。配列オブジェクトと表現同じ配列オブジェクトの最後の要素にQポイントの要素に発現Pポイント場合、ポインタ式Q+1超える Pとを比較します。他のすべてのケースでは、その動作は未定義です。

ポインタが配列の範囲内にあることがわかっている場合は、比較が機能します。ポインタが範囲外にある場合は、比較が機能することを確認することはできません。実際には、通常そうしていますが、標準では、比較によって未定義の動作が生じることが明示されています。

注配列SomeType array[20];ため、アドレス&array[20]は有効であると&array[19]を通じて&array[0]から任意のアドレスに確実に比較することが保証されていること。配列内にあるかどうかを判断する必要があるかどうかを判断する必要があります。これらの日

int within_int_array(int *array, size_t num_ints, int *ptr) 
{ 
    return ptr >= array && ptr < array + num_ints; 
} 

、あなたは未定義の動作を呼び出すことについて、ますます注意が必要です:標準は、その後、あなたは2つのintポインタを比較することができ、それが動作することを保証するものではないという観察に

件名。コンパイラは、未定義の振る舞いを使用するプログラムに対しては厄介なことを行いますが、技術的には、標準で「未定義の振る舞い」と言われています。

+0

大きな[〜100000]配列についての以前のコメントについて:配列に対してしばしばテストする必要がある場合、配列への有効なポインタをすべて 'uintptr_t'にキャストしてハッシュテーブルを作成できませんでした。次に、ポインタ 'p'が配列の要素を指しているかどうか調べるために' p'を 'uintptr_t'にキャストし、結果をハッシュしてテーブルをチェックします。それともこれはちょっと悪い考えですか? –

+1

@DavidBowling:それはハッシュテーブルなのかもしれませんが、それほどインフラストラクチャを必要とするよりポインタがどこを指しているかを知るほうが助かります。 –

関連する問題