Search code examples
c++pointerscachingundefined-behaviorpointer-arithmetic

How can I get the memory distance in bytes between any two objects (if this measurement exists in a meaningful way)?


Pointer arithmetic is only defined behavior for pointers to elements of the same array (or one past the array).

Is there any defined behavior to get the distance in memory between two elements that are not in the same array?

For example, say I have a function that jumps around in memory to access values to calculate something (values not in the same array or object). I want to know how big the jumps are (and print them out, in bytes) to determine if cache misses might occur and their severity. Is this possible?

If my understanding is correct that a pointer contains an absolute virtual address (absolute for a given process), then within a process it seems to make intuitive sense that this should be possible.


Solution

  • Is there any defined behavior to get the distance in memory between two elements that are not in the same array?

    No, generally this doesn't exist because memory doesn't even need to have a flat layout in which this would make sense.

    However, in most implementations you can do

    auto addr1 = reinterpret_cast<std::uintptr_t>(&obj1);
    auto addr2 = reinterpret_cast<std::uintptr_t>(&obj2);
    auto distance = addr1 >= addr2 ? addr1-addr2 : addr2-addr1;
    

    The behavior and mapping used by the cast is however implementation-defined and doesn't have to relate to addresses on the system.

    For example, say I have a function that jumps around in memory to access values to calculate something (values not in the same array or object).

    Note that even if the above is possible on the implementation, then you are generally still not allowed to simply use the numeric values obtained above to reconstruct a pointer to some object somewhere in memory with reinterpret_cast and access that.

    The whole point for the restrictions on pointer arithmetic is that the compiler is permitted to assume that it is impossible to reach from one memory allocation or variable to another memory allocation or variable. That is necessary to make various kinds of analysis possible for optimization.

    But for checking alignment and such this is a valid approach.