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

时间:2017-04-30 17:03:29

标签: c++ pointers pointer-arithmetic

我希望能够使用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指针访问值?

2 个答案:

答案 0 :(得分:3)

我找不到一个好的重复答案,所以这就是正在发生的事情:

指针算法总是以指针的基本类型为单位进行。也就是说,当你有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。这会为您提供int之后的第32 basepointer个地址。如果您的平台使用4字节整数,则实际偏移量为32 * 4 = 128字节。这是我们存储455的地方。

然后你做

void *p = basepointer + 32;

这是技术上无效的代码,因为basepointervoid *,并且您无法对void进行算术运算,因为void没有大小。作为扩展,gcc支持此功能并假装void的大小为1。 (但你真的不应该依赖于这个:如果你想要按字节顺序地转换为unsigned char *。)

现在p32后偏移basepointer

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

这将从上面重复指针运算,并从int偏移32(即字节偏移128)中检索值,该值仍为455

b = *((int*)p);

这将检索存储在字节偏移int的{​​{1}}值(在此示例中,它对应于32偏移量int)。我们从未在此处存储过任何内容,因此8基本上是垃圾(在您的平台上恰好是b)。

使此代码按预期工作的最小变化可能是

0

答案 1 :(得分:0)

无效指针算法在C / C ++中是非法的,GCC允许它作为扩展。

您需要修改此行:

    var total=0;
if (productContainer) {
    productContainer.append(buyNowButton);
    var clickHandler = function(event){ 
    $(event.target).is("button");
    $(".cart").append(this);
    price=$(this).find('.price').text();
    total+=parseFloat(price.replace("$", ""));
    $(".total").text("Total: $"+total);
}

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

对于void,如果编译器允许,则为sp + 3 = sp + 3 *sizeof(short) = 4006