版本1:
int* work(int** pointer, int offset)
{
return *pointer + (offset/sizeof(int));
}
int main()
{
int** pointer = (int**) 0x4df73c;
int offset = 0xf4;
int* healthLowestPointer = work(pointer, offset);
while(true) {
*healthLowestPointer = 1000;
Sleep(250);
}
}
第2版:
int* work(int* pointer, int offset)
{
return (int*) (*pointer + (offset/sizeof(int)));
}
int main()
{
int* pointer = (int*) 0x4df73c;
int offset = 0xf4;
int* healthLowestPointer = work(pointer, offset);
while(true) {
*healthLowestPointer = 1000;
Sleep(250);
}
}
版本1正常工作,但版本2似乎没有。我不明白为什么版本2被破坏了。是不是取消引用双级指针与取消引用单级指针相同,即它抓取指针包含的内存地址的值?
如何编写一个以n级指针作为输入的函数,并通过解除引用n级指针n-1次返回1级指针?
答案 0 :(得分:2)
他们是非常不同的东西。 int**
是指向int
的指针。如果您取消引用它,则会得到int*
。 int*
是指向int
的指针。如果您取消引用它,则会得到int
。
在第一个示例中,您将值int**
的{{1}}作为0x4df73c
的第一个参数传递。然后你取消引用它,这应该给你一个work
。也就是说,int*
是地址的地址,而0x4df73c
让你成为第二个地址。然后通过添加*pointer
对此int*
进行指针运算,计算出(offset/sizeof(int))
个字节的int
个offset
。因此,当您添加此值时,int*
将移动到指向该偏移处的int
。然后返回此int*
,一切顺利。
在第二个示例中,您将0x4df73c
作为int*
传递。然后你取消引用它,它会给你一个int
。现在+
不做指针算术 - 它做整数运算。 (offset/sizeof(int))
仍会以int
个字节为您提供offset
s的数量,但算术将无法执行您想要的操作。它不会将int
的值增加适当的数量。
假设您的计算机上int
为4个字节。当您int*
被称为p
而p + 5
时,5
只会将p
添加到5
中的地址。它会增加int
({1}}(20个字节)大小的int
倍,因此它现在指向第5个int
。但是,如果您有一个名为i
的{{1}}而i + 5
,那么这只会添加5
。
这就是你的问题。当您添加到int
,时,您没有进行适当的算术。我认为如果你把它更改为将工作,假设你的系统int*
和int
大小相同(正如你所说的那样):
return (int*) (*pointer + offset);
但我不推荐此。不要使用int
,就好像它是指针一样。 (int*)
的演员阵容涉及reinterpret_cast
并且非常糟糕。坚持你的第一个代码。
答案 1 :(得分:0)
指针算术和整数运算不是一回事。
忽略写入您正在使用的位置是否有效的问题,请考虑以下结果:
int i=5;
int j=i+1; // now j==6
int* pi = &i; // let's say pi is 0x1000
int* pj = &i+1 // now pj is 0x1000 + (sizeof int)