2013-03-18 9 views
10

voidポインタをキャストした後でも、逆参照中にコンパイルエラーが発生します。 誰でも私にこれの理由を教えてもらえますか?Dereference void pointer

int lVNum = 2; 
void *lVptr; 
lVptr = (int*)&lVNum; 

printf("\nlVptr[60 ] is %d \n",lVptr[1]); 
+0

を逆参照することはできませんvoidポインタ実際のコンパイルエラーは何ですか? – MatthewD

+17

4行のコードでは、(a)不要なキャスト、(b)型なしポインタの不正な参照解除、(c)範囲外の未定義の動作があります。それは新しい記録かもしれない。 – WhozCraig

+0

コンパイラのエラーは何ですか?実際のエラー自体がなくてもエラーの理由を説明するのは難しいです。 –

答えて

12

printf("\nlVptr[60 ] is %d \n", *(int*)lVptr);

これはintへのポインタにボイドポインタをキャストし、それを逆参照を正しくます。

(1つの)配列として扱いたい場合は、少し醜い((int *)lVptr)[0]を実行できます。 [1]を使用すると範囲外です。したがって、良い考えではありません(lVptr[60] ...)

4

これはあなたがそれを宣言したものなので、それはまだです。どのポインタも暗黙的にvoid*に変換されるので、キャストは何もせず、最初にvoidへのポインタが残ります。

int*と宣言する必要があります。 int*キャストがあなたがする必要はありません(とないはずです)C.

mallocの戻り値をキャストするのと同じ理由のために、また不要であることを

void *some_ptr = /* whatever */; 
int *p = (int*)some_ptr; 
// now you have a pointer to int cast from a pointer to void 

注意void*は他のポインタ型との間で暗黙的に変換できます。ここでは、わかりやすくするためにキャストを追加しました。

int *p = some_void_ptr; 

また、この:

lVptr[1] 

が間違っています。 2つではなく、1つのintへのポインタがあります。その参照は未定義の動作を引き起こします。

+0

+1この中に残されているのは、C言語では必要ないキャストだけです。それ以外は、これですべてが解決されます。 – WhozCraig

+0

@WhozCraig:そうですね、できるだけ明確にしたいと思っていました。私はそれを言及すべきだと思います。将来は愚かな 'malloc'キャストを防ぐかもしれない。 –

+0

ええ。 "//キャストは不要(または推奨)ですが、あなたがしていることを増幅します。"依然としてup-vote = P – WhozCraig

15

voidポインタを逆参照することは意味がありません。コンパイラは、ポインタが指しているメモリをどのように解釈しますか?あなたは、まず適切な型へのポインタをキャストする必要があります。

int x = *(int*)lVptr; 
+1

これが正解でなければなりません – thiagoh

+0

なぜコンパイラはメモリの解釈を気にする必要がありますか?それは私がその記憶を操作する操作までではないのですか? – Ungeheuer

+0

メモリを操作するには、 '+'のような演算子を使う必要があり、演算子の振る舞いはどちらの整数型に依存します。あるいは単にメモリを読み込むだけでも、コンパイラが読み込むバイト数を知るように型を指定する必要があります。自由形式でメモリにアクセスしたい場合は、ポインタを 'uint8_t *'にキャストしてください。 –

0

voidポインターは空白(何も定義できません)へのポインターです。

場合によっては便利です。 たとえば、malloc()は空白ポインタを正確に返します。なぜなら、それがUNDEFINED目的のためにメモリを割り当てたからです。 一部の関数は、場所以外の実際の内容を気にしないので、voidポインタを引数として取り込むこともできます。

あなたが投稿したスニペットは絶対に意味をなさない、あなたがしようとしていることを推測することはできません。あなたがやろうとするかもしれないものの

0

例:

#include <stdio.h> 

int main() { 
    void *v; 
    unsigned long int *i = (unsigned long int *)v; 

    *i = 5933016743776703571; 

    size_t j = sizeof(i); 
    printf("There are %ld bytes in v\n", j); 

    size_t k; 
    for (k = 0; k < j; k++) { 
     printf("Byte %ld of v: %c\n", k, ((char *)v)[k]); 
    } 
} 

が出力:コード-達人 @

There are 8 bytes in v 
Byte 0 of v: S 
Byte 1 of v: T 
Byte 2 of v: A 
Byte 3 of v: C 
Byte 4 of v: K 
Byte 5 of v: O 
Byte 6 of v: V 
Byte 7 of v: R 
0

私は、Visual Studioでコンパイルしてみました。それはエラーを与えます - 式はオブジェクトを完成させるためのポインタでなければなりません。

おかげです、 提案したとおり、次のようにコンパイルして正しい結果が得られます。しかし

#include<stdio.h> 

void main(){ 

printf("study void pointers \n"); 

int lvnum = 2; 
void *lvptr; 
lvptr = &lvnum; 
printf("\n lvptr is %d\n",((int *)lvptr)[0]); 


} 

私はprintfのしてみてください( "\ n個をlvptr%dは\ nのである"、((int型*)lVptr)[60])場合。 コンパイルして実行しますが、乱数を与えます。

すべての提案をいただきありがとうございます。不必要にキャストされたintポインタへのvoidポインタを割り当て、逆参照されることを期待していたことをお詫び申し上げます。しかし、私はそれを逆参照したいときにキャストしておくべきでした。

スニペットの目的: 私のソースでは、同様の状況によって引き起こされたklocworkエラーが見つかりました。逆に、プログラムだけでなく、正しい結果を与えたコンパイル。理由 - これはボイドポインタに割り当てられたメモリがすでに60のようなカウントまで予約されている低レベルのコードです(OSはありません)。しかし、klocworkツールはその制限を持つファイルを解析できなかったため、エラーになります。私は多くの脳を襲ってしまい、何かばかげてしまった。

Saurabh

2

あなたはそれが型を持っていないので、それをキャストする 最初の必要性は、ボイドポインタを逆参照して、あなたは間接参照することはできません*(int型*)lVptr

int lVNum = 2; 
void *lVptr; 
lVptr = &lVNum; 

printf("\nlVptr[60 ] is %d \n",*(int *)lVptr); 
関連する問題