Tuntuni
Tuntuni

Reputation: 491

C++ Integer to pointer conversion

So recently I've been dealing with WinAPI's WriteProcessMemory and ReadProcessMemory which both take LPVOID as their second argument which is the actual address in the memory of another process we want to read from.

Considering that, would this integer to pointer conversion be correct C++ code (without undefined behavior, etc.):

#include <windows.h>
int main()
{
    WriteProcessMemory(/*...*/,
        //want to read from memory address 0x1234 in the target process
        reinterpret_cast<void*>(static_cast<uintptr_t>(0x1234)),
        /*...*/);

    return 0;
}

AFAIK, the standard says that uintptr_t is an integer type which is able to hold a pointer without the value of the pointer being changed. Since it is an integer, I should be able to store 0x1234 in it. The standard also says that reinterpret_casting an uintptr_t to a void* will also leave the value unchanged.

Upvotes: 3

Views: 1215

Answers (1)

bbonev
bbonev

Reputation: 1438

On Windows platforms the pointer is stored exactly in the same way as the same bit-count integer type. The difference is how the compiler interpretes the value of a pointer and an int. So no conversion is neccessary.

Casting it to void */LPVOID is just to make the compiler happy and accept the integer value in a place for pointer and no conversion is made. Going through static_cast+reinterpret_cast is overkill in this case.

As long as you are sure that the correct address is 0x1234, conversion is not needed. Just a plain (LPVOID)0x1234 or (void *)0x1234 should do.

[edit] As noted in the comments the constant may get truncated. Then no conversion can fix the pointer value. A way to handle this is to explicitly specify the type used in the constant:

E.g. (void *)0x1234567812345678ULL will be OK because the compiler is instructed to use 64bit unsigned type.

Upvotes: 1

Related Questions