0

I get an access violation reading location when I try the following. What am I doing wrong?

uint64_t hInt = 2901924954136;
void* hPoint = reinterpret_cast<void*>(hInt);

uint64_t hIntBack = *static_cast<uint64_t*>(hPoint); //get access violation 
here
user3294816
  • 37
  • 1
  • 7
  • 1
    I assume there's no accessible memory at 2901924954136. – Steve Aug 13 '17 at 05:35
  • What is the magic in address `2901924954136`? Why are you trying to dereference it? – PaulMcKenzie Aug 13 '17 at 05:47
  • 1
    Note how at `void* hPoint = reinterpret_cast(hInt);` you did not take the address of `hInt`. This means you are doing something other than undoing here `*static_cast(hPoint);`. Most likely you have told the computer to get you a `uint64_t` at address 2901924954136. – user4581301 Aug 13 '17 at 05:47
  • `What am I doing wrong?` You try to read data from memory `*static_cast(hPoint);` If you try to do what you write in the headline: `access violation casting to void* and back` then you need: ` uint64_t hIntBack = reinterpret_cast(hPoint);`. – Gluttton Aug 13 '17 at 05:47

2 Answers2

4

I am guessing you meant to store the address of hInt in hPoint, not the value of hInt.

uint64_t hInt = 2901924954136;
void* hPoint = reinterpret_cast<void*>(&hInt);
                                    // ^ addressof operator
R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

What you do is the following:

  • cast an integer to a void pointer - fine, but the pointer may point to not available memory.
  • cast the void pointer to an pointer to unsigned 64 bits integer - fine, but because of the way you got it, dereferencing it is Undefined Behaviour
  • dereference the pointer and UB gives access violation here

Casting a pointer to int to a pointer to void and back again is fine (RSahu answer), or even casting an int to a pointer and back can be (*) so this would be fine:

uint64_t hInt = 2901924954136;
void* hPoint = reinterpret_cast<void*>(hInt);

uint64_t hIntBack = static_cast<uint64_t>(hPoint);

On system where pointers use at least 64 bits (almost any current system), standard guarantees that hIntBack has same value as hInt. On old systems where pointers are less than 64 bits long, you will lose the highest order bits.


(*) In fact this is not defined by C++ standard, but is by C99. As common compilers process both languages, casting a pointer to an integer the size of which is big enough and back again will be accepted by most common compilers.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • I'm not sure that casting an integer to a pointer is technically fine. Sure, on x86 nothing bad will happen, but as far as the standard is concerned IIRC even just *creating* a pointer that points to invalid memory triggers some access violation (on some platforms the check is performed when loading it into a pointer-register, not just when dereferencing). – Matteo Italia Aug 13 '17 at 06:40
  • @MatteoItalia it depends whether the implementation has *relaxed pointer safety* or not (this is implementation-defined) – M.M Aug 13 '17 at 08:32
  • 1
    This answer says "Casting a pointer to int...is fine" but then gives an example of casting an int – M.M Aug 13 '17 at 08:34
  • @M.M: the example cast an int to a pointer and back to an int. But I've added the precision that this is an extension allowed in C language – Serge Ballesta Aug 13 '17 at 09:06