Version 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);
}
}
Version 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);
}
}
Version 1 works correctly, but version 2 doesn't seem to. I don't understand why version 2 is broken. Isn't dereferencing a a double-level pointer the same thing as dereferencing a single-level pointer i.e. it grabs the value at the memory address the pointer contains?
How would I write a function that takes a n-level pointer as input, and returns a 1-level pointer by dereferencing the n-level pointer n-1 times?
They are very different things. An
int**
is a pointer to a pointer to anint
. If you dereference it, you get anint*
. Anint*
is a pointer to anint
. If you dereference it, you get anint
.In the first example, you pass an
int**
with value0x4df73c
as the first argument towork
. You then dereference this, which should give you anint*
. That is,0x4df73c
is the address of an address and doing*pointer
has gotten you the second addess. You then do pointer arithmetic with thisint*
by adding(offset/sizeof(int))
, which works out how manyint
s there are withoffset
bytes. So when you add this value, yourint*
will move along to point at theint
at that offset. You then return thisint*
and all is well.In the second example, you pass
0x4df73c
as anint*
. You then dereference it, which gives you anint
. Now the+
doesn't do pointer arithmetic - it does integer arithmetic.(offset/sizeof(int))
will still give you the number ofint
s inoffset
bytes, but the arithmetic won't do what you want. It won't increase the value of theint
by the appropriate amount.Let's say an
int
is 4 bytes on your machine. When you have anint*
calledp
and you dop + 5
, this doesn't just add5
to the address inp
. It adds5
times the size of anint
(20 bytes), so that it's now pointing at the 5thint
. However, if you have anint
calledi
and you doi + 5
, this really does just add5
.So that's your problem. When you add to the
int
, you're not doing the appropriate arithmetic. I imagine it would work if you change it to, assuming anint*
and anint
are the same size on your system (as you say they are):but I do not recommend this. Don't use an
int
as though it were a pointer. The cast to the(int*)
involves areinterpret_cast
and is horrible. Stick to your first code.