为什么我不能用C++中的不同指针访问int?
我希望能够用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指针访问值?
我不能找到一个很好的答案重复,所以这里发生了什么:
指针运算总是在指针的基本类型的单位发生。也就是说,当您有T *ptr
(指向某种类型的指针T
)时,则ptr + 1
不是内存中的下一个字节,而是下一个T
。
换句话说,可以想像这样的阵列的组合和索引的指针:
T *ptr;
T array[/*some size*/];
ptr = &array[n];
如果ptr
是指向array[n]
(第n个元素),然后ptr + i
是指向array[n + i]
(第(n + i)个元素)。
让我们来看看你的代码:
*((int*)basepointer+32) = 455;
在这里,我们铸造basepointer
到(int*)
,然后加入32
它。这给了你basepointer
后第32nd int
的地址。如果您的平台使用4字节整数,则实际偏移量为32 * 4 = 128
字节。这是我们存放455
的地方。
然后你做
void *p = basepointer + 32;
这在技术上是无效的代码,因为basepointer
是一个void *
,你不能在void
方面做算术题,因为void
没有大小。作为扩展,gcc支持这个并假装void
具有大小1
。
现在p
是basepointer
抵销后32
:(如果你想按字节寻址投地unsigned char *
但你真的不应该依赖于这一点。)。
a = *((int*)basepointer+32);
这从上方重复指针算术和检索来自int
偏移32的值(即字节偏移128
),这仍然是455
。
b = *((int*)p);
此检索存储在字节int
值偏移32
(其将对应于int
抵消在该示例8
)。我们从来没有在这里存储任何东西,所以b
本质上是垃圾(它恰好在您的平台上为0
)。
最小的变化,使这个代码按预期方式工作可能是
void *p = (int *)basepointer + 32; // use int-wise arithmetic to compute p
空指针运算是在C/C++是非法的,GCC允许它作为扩展。
需要修改这一行:
void *p = basepointer + 32;
到
void *p = basepointer + 32 * sizeof(int);
由于指针运算比较计算类型的大小。
例如:
sizeof (int) = 4
如果和 sizeof(short) = 2
int *p
和具有3000
和short *sp
地址具有4000
然后p + 3 = p + 3 * sizeof(int) = 3012
和sp + 3 = sp + 3 *sizeof(short) = 4006
如果编译器允许,则为1
。
尝试'*(int *)(basepointer + 32)= 455;'而不是第二行。然后去阅读指针算术。 – aragaer
@aragaer如果'basepointer'的类型为'void *',这不是个好主意。 – aschepler
basepointer的类型是什么? – Bathsheba