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 value0x4df73cas the first argument towork. You then dereference this, which should give you anint*. That is,0x4df73cis the address of an address and doing*pointerhas gotten you the second addess. You then do pointer arithmetic with thisint*by adding(offset/sizeof(int)), which works out how manyints there are withoffsetbytes. So when you add this value, yourint*will move along to point at theintat that offset. You then return thisint*and all is well.In the second example, you pass
0x4df73cas 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 ofints inoffsetbytes, but the arithmetic won't do what you want. It won't increase the value of theintby the appropriate amount.Let's say an
intis 4 bytes on your machine. When you have anint*calledpand you dop + 5, this doesn't just add5to the address inp. It adds5times the size of anint(20 bytes), so that it's now pointing at the 5thint. However, if you have anintcallediand 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 anintare the same size on your system (as you say they are):but I do not recommend this. Don't use an
intas though it were a pointer. The cast to the(int*)involves areinterpret_castand is horrible. Stick to your first code.