KYL3R
KYL3R

Reputation: 4073

EXCEPTION_ACCESS_VIOLATION (read from address 0xffffffffffffffff)

I want to know how to interpret 0xffffffffffffffff (in backtraces)

I know:

  1. reading from 0 / nullptr is a not valid address.

  2. reading from 0x58, after the object there was deleted, will result in access violation, because I do not own the memory location.

So for 0xffffffffffffffff, I know / assume:

  1. It's a 64 bits pointer
  2. Object behind it is probably not deleted
  3. object* obj; would create pointer of type object* on the stack, value 0 / nullptr.
  4. object* obj = new object() would create object on heap, store pointer to it in obj, with a valid address like 000000000BD0ADA0 - needs to be deleted with delete obj at some point.
  5. 0xffffffffffffffff is all 1s in binary.

Question: How do I end up with 0xffffffffffffffff

  1. sounds like a underflow or something, why?
  2. can this be related to the compiler, or the debugger?
  3. why is it 0xffffffffffffffff ?
  4. How should I interpret this?

In my specific case, it's like this:

  1. CustomItem* name_item = new CustomItem (i, elems[i]);
  2. Custom Item constructor

CustomItem (int sort_val, MyObject *obj) : _sort_val (sort_val), _mobj(obj) { }

  1. model->setItem (i, 0, name_item);
  2. #0 Qt5Gui public: void cdecl QStandardItemModel::setItem(int,int,class QStandardItem * ptr64) ptr64 +0xd (ip 0x7fee721bcfd fp 0x168470)

Upvotes: 0

Views: 5398

Answers (2)

carbin
carbin

Reputation: 3027

The x86_64 CPUs available today only implement a 48-bit address space, not the full 64-bits.

If you dereference a pointer that is outside the hardware address space it raises a fault. Windows reports this as an Access Violation but passes the address parameter as 0xffffffffffffffff instead of the real invalid address.

If you declare any variable and do not initialise it, its value can be that of random stack junk. If you declare a pointer and do not initialise it, it can effectively point at a random address, and that address can be outside the hardware address space.

If you really want to know what address was being accessed, you can look at the disassembly to see what register was being accessed and then look at the value of that register.

Upvotes: 0

KYL3R
KYL3R

Reputation: 4073

Comments: It's probably an uninitialized pointer.

I found that:

Object* obj; // is 0

However:

Object* obj1; // is 0
Object* obj2 = new Object(); // is 000000000BF6F100 (some valid address)
Object* obj3; // is 000000000BF6F100 

Conclusion: Object* obj; is not guaranteed to be 0.

Compiler or Debugger probably replaces uninitialized pointers to 0xffffffffffffffff. Apparently only in some cases, because I could not reproduce it in a simple example. I'd like to have a link to some c++ specification, compiler specification or maybe visual studio debugger, that proved this.

Upvotes: 0

Related Questions