为什么我不能在 C++ 中使用不同的指针访问 int?

Why can't I access int with different pointer in C++?

我希望能够使用 p 指针访问值。但是当我使用 p 指针时,我总是让 b 变量等于零。请参考下面的代码片段。

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 之后第 32 个 int 的地址。如果您的平台使用 4 字节整数,则实际偏移量为 32 * 4 = 128 字节。这是我们存储 455.

的地方

然后你做

void *p = basepointer + 32;

这在技术上是无效的代码,因为 basepointer 是一个 void *,并且您不能根据 void 进行算术运算,因为 void 没有大小。作为扩展,gcc 支持这个并假装 void 的大小为 1。 (但是你真的不应该依赖这个:如果你想要按字节寻址,则转换为 unsigned char *。)

现在 pbasepointer 之后的偏移量 32

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

这会重复上面的指针运算,并从 int 偏移量 32(即字节偏移量 128)中检索值,它仍然是 455.

b = *((int*)p);

这将检索存储在字节偏移量 32 处的 int 值(在本例中对应于 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) = 4sizeof(short) = 2

int *p的地址为3000
short *sp 的地址为 4000

然后 p + 3 = p + 3 * sizeof(int) = 3012
sp + 3 = sp + 3 *sizeof(short) = 4006

对于 void 它是 1 如果编译器允许的话。