我希望能够使用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指针访问值?
答案 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;
这是技术上无效的代码,因为basepointer
是void *
,并且您无法对void
进行算术运算,因为void
没有大小。作为扩展,gcc支持此功能并假装void
的大小为1
。 (但你真的不应该依赖于这个:如果你想要按字节顺序地转换为unsigned char *
。)
现在p
在32
后偏移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
。