2017-04-30 5 views
0

pポインタで値にアクセスできるようにしたい。しかし、私はpポインタを使用するとき、私は常にb変数をゼロに等しくしています。以下のコードスニペットを参照してください。C++で異なるポインタでintにアクセスできないのはなぜですか?

basepointer = malloc(512);  
*((int*)basepointer+32) = 455; // putting int value in memory 
void *p = basepointer + 32;  // creating other pointer 
int a,b; 
a = *((int*)basepointer+32); // 455, retrieving value using basepointer 
b = *((int*)p);     // 0, retrieving value using p 

どうしてですか? pポインタで値にアクセスするにはどうしたらいいですか?

+1

代わりに2行目で '*(int *)(basepointer + 32)= 455;'を試してください。次に、ポインタ演算について読んでください。 – aragaer

+1

@aragaer 'basepointer'が' void * '型を持っていると良い考えはありません。 – aschepler

+0

ベースポインタの種類は何ですか? – Bathsheba

答えて

3

私は良い重複答えを見つけることができないので、ここで何が起こっているのです:

ポインタ演算は常にポインタの基本型の単位で行われます。つまり、T *ptr(あるタイプのポインタT)を持っている場合、ptr + 1はメモリの次のバイトではなく、次のTです。すなわち

、アレイとインデックスの組み合わせのようなポインタを想像することができるが:

T *ptr; 
T array[/*some size*/]; 
ptr = &array[n]; 

ptrarray[n]へのポインタ(n番目の要素)である場合、ptr + iarray[n + i]へのポインタであります((n + i)番目の要素)。

はのは、あなたのコードを見てみましょう:あなたはそれに 32を追加し、その後、 basepointer(int*)をキャストしている。ここ

*((int*)basepointer+32) = 455; 

。これにより、basepointerの後に32番目のintのアドレスが表示されます。プラットフォームが4バイトの整数を使用する場合、実際のオフセットは32 * 4 = 128バイトです。ここには455が保管されています。

は、その後、あなたはbasepointervoid *あるので、これは技術的に無効なコードで、voidは何のサイズを持っていないので、あなたはvoidの面で算術演算を行うことはできません

void *p = basepointer + 32; 

を行います。拡張として、gccはこれをサポートし、voidのサイズは1です。 (しかし、あなたが本当にこれに頼るべきではありません:あなたはアドレス指定をバイト単位たい場合unsigned char *へのキャスト)

pがでbasepointer32オフセットされます。

a = *((int*)basepointer+32); 

これは上からポインタ演算を繰り返し、依然として455ある32をオフセットintの値を(すなわち、バイト128オフセット)、検索します。

b = *((int*)p); 

これはバイトで保存int値が32intに対応するこの例では8オフセット)オフセットを取得します。ここには何も格納されていないので、bは本質的にはガベージです(プラットフォーム上では0)。


このコードを動作させるための最小の変化予想通り、おそらく

void *p = (int *)basepointer + 32; // use int-wise arithmetic to compute p 
0

ボイドポインタ演算は、C/C++で違法である、GCCは拡張として可能。ポインタ演算は、型サイズに相対的に計算されますので、

void *p = basepointer + 32; 

void *p = basepointer + 32 * sizeof(int); 

へ:

あなたはこの行を変更する必要があります。例えば

sizeof (int) = 4sizeof(short) = 2

int *p3000
のアドレスを持ち、short *sp4000

次いでp + 3 = p + 3 * sizeof(int) = 3012
sp + 3 = sp + 3 *sizeof(short) = 4006

0のアドレスを有する場合

voidの場合、コンパイラで許可されている場合は1です。

関連する問題