6

一般的な値を保持できる構造体を作成しようとしています。以下のコードは機能しますが、ポインターから整数へのキャストについてコンパイラーの警告が表示されます。これは64ビットシステム上にあります。

struct node
{
    void *key;
    void *value;
};

void insert(struct node *ht, void *key, void *value)
{
    ht->key = key;
    ht->value = value;
    return;
}

int main()
{
    struct node *t = (struct node *)malloc(sizeof(struct node));
    insert(t, (void *)3, (void *)5);
    printf("[%d]->[%d]\n", (int)t->key,(int)t->value);
    free(t);
    return 0;
}

これが正しい方法かどうかさえわかりません。私はそれをちょっとハックしました。これを行う適切な方法があるかどうか教えてください。

4

3 に答える 3

9

void *コンパイラは、からにキャストするときにビットが失われることを警告しようとしますintvoid *が実際にキャストであるかどうかはわからないintため、失われたビットは無意味です。

ダブルキャストはこれを解決し(int)(uintptr_t)t->keyます。
最初に(同じサイズ、警告なし)にキャストvoid *し、次に(数値から数値、警告なし)にキャストします。タイプ(ポインターと同じサイズの整数タイプ)を持つ ために含める必要があります。uintptr_tuintptr_tint
<stdint.h>uintptr_t

于 2013-02-05T15:54:53.770 に答える
3

覚えておくと便利なことの1つは、64ビットシステムでは、ポインタは64ビット値[メモリアドレス]であるということです。

使用しているアーキテクチャに関係なく、intは32ビット値にすぎません。明示的にキャストせずに64ビット値を32ビット値に割り当てようとすると、コンパイラは警告をスローします[もちろん、それでも機能する可能性がありますが、一般的にはお勧めできません。]

符号なし整数の使用を嫌がらない場合は、uint_64tなどを使用する方が簡単な場合があります。これにより、64ビットから32ビットへの割り当てが回避されます(uint_64tは符号なし64ビットintです)。

お役に立てば幸いです。

あなたができることの1つは次のとおりです。

int key = 3;
int value = 5;
insert(t, (void *) &key, (void *) &value);
printf("[%d]->[%d]\n", (int) *(t->key), (int) *(t->value));

ただし、このようなことを行うときは非常に注意してください。ポインタを設定し、その値/型が変更されていないことを保証できない限り、そのポインタによって格納されている値を完全に知ることは不可能です。ポインタの場所に格納されている値の型を格納する列挙型フィールドなどを追加しない限り、そのようなものは目的を損ないます。

于 2013-02-05T16:57:33.823 に答える
2

投稿したコードには多くの問題があります。

初め:

printf("[%d]->[%d]\n", (int)t->key,(int)t->value);

ポインタを印刷するときは、ポインタを印刷してください。%pを使用します。ここを参照してください:

http://www.cplusplus.com/reference/cstdio/printf/

2番:

insert(t, (void *)3, (void *)5);

何が起こるかわかりませんが、値ではなくアドレスを保存しています。(つまり、キーをアドレス3の内容へのポインターとして設定し、値をアドレス5の内容へのポインターとして設定します)。

第3:

struct node *t = (struct node *)malloc(sizeof(struct node));

ここではノードを割り当てましたが、コンテンツを保持するために何も割り当てていません。ノードはいくつかのポインター(ADDRESSES)を保持しているだけで、VALUESは保持していません。これがあなたの望むものかどうかはわかりません。

最後に、あなたのコンパイラはあなたに警告している。精度が低下する可能性があります。@JonathanLefflerが言ったように、uintptr_tを使用します。

于 2013-02-05T16:50:10.757 に答える