1

voidポインタを取得する関数を作成したいと思います。このポインタは、任意のユーザーデータを指します。これは現在は関係ありません。これは、このユーザーデータを説明する記述子としてより重要です。このデータの下にあります。アドレスを取得したいのですが、2つの異なる解決策があります。

struct data_desc {
     size_t size;
     data_type_t type;
     /* And so on... */
};

/* Operate on the descriptor */
void operate_on_data(void *ptr)
{
    struct data_desc *desc;
    /* Now I want to get the desc /*

    /* This is the first approach, simply fails */
    desc = ((struct data_desc *)ptr) - sizeof(struct data_desc);
    /* This is the second, it works...*/
    desc = (struct data_desc *)ptr;
    desc--; 
    /* Do something with desc */
}

ご覧のとおり、記述子のアドレスを取得するために2つの異なるアプローチを使用しています。最初の方が自然だと思いましたが、うまくいきません。優先順位の問題を回避するために、より多くの括弧を使用しました。

私はこれらの方法が安全ではないことを知っています。最初のものは機能しません、なぜですか?この動作の背後にある理由は何ですか?

前もって感謝します!

4

3 に答える 3

2

問題はポインタ演算です。ポインタを取り、1を引くと、実際にはを減算し(1*sizeof(struct))ます。「-sizeof」を使用した最初の式では、実際に(sizeof(struct) * sizeof(struct))はポインターからバイトを減算しています。わかる?

于 2012-04-23T01:52:50.743 に答える
1

data_descへのポインタとして定義する場合struct data_desc、コンパイラsizeof(struct data_desc)は、ポインタを1つインクリメントまたはデクリメントするときに加算または減算することを認識しています。つまり、「1つ」を「1つの構造」に変換します。

次のようなコードを書くのが一般的です。

struct data_desc *desc = (struct data_desc *) ptr;

次に、次のように操作できます。

size_t sz0 = desc->size;  // size of 0th element
size_t sz1 = desc[1].size;  // size of 1st element
size_t sz2 = (desc + 2)->size; // size of 2nd element (slightly awkward)
desc++;  // Increment to next structure

元のコードに戻る:を書くことはできdesc = ((struct data_desc *)ptr) - 1;ますが、ほとんどのプログラマーは初期化descしてから直接使用することを好みます。

于 2012-04-23T01:48:32.897 に答える
1
desc = ((struct data_desc *)ptr) - sizeof(struct data_desc);

に型キャストptrしましたstruct data_desc *。これで、コンパイラがこのポインタに対して行うすべての演算は、ポインタが指す型のサイズのチャンクになります。

したがって、減算するsizeof(struct data_desc)と(たとえばstruct data_desc、サイズが8バイトの場合)、は、それ自体との間ptrに8を収めることができる場所を指します。struct data_descptr

loc以下のそれぞれが1つを保持できると仮定しますstruct data_desc

-------------------------------------------------------------
|     |     |     |     |     |     |     |     |     |     |
| loc | loc | loc | loc | loc | loc | loc | loc | loc | ptr | 
|  9  |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |     |
-------------------------------------------------------------
      ^                                               ^
      |                                               |
     desc                                            ptr 
     location                                        location
     after
     subtraction           
于 2012-04-23T01:56:52.200 に答える