1

I'm trying to learn c++ and I found this awesome graphic to help me understand how content is stored across multiple addresses.

enter image description here

So, would it be true to say that if I created a pointer to sum like int* p = &sum that the address would be 90000000. And if that's the case, what value would I get if I tried to dereference a pointer at the address 90000001? Do all of those addresses just point to the same 4 bytes/content?

Alec Mather
  • 742
  • 5
  • 20
  • 2
    It depends on what kind of pointer you're trying to dereference. If you're trying to dereference an `int*` pointer, you get undefined behavior because it doesn't actually point to a valid `int` so all bets are off. If you're trying to dereference a `char*` pointer you got by reinterpret casting, you can get a pointer to the individual byte stored there. – Nathan Pierson Nov 07 '22 at 06:06
  • 3
    If you dereferenced `900000001` as an `int` you would get undefined behaviour according to the standard. There is no guarantee about how distinct variables are laid out in memory. In your example with an `int`, a `short`, and a `double` the order is not guaranteed, and there may be padding between variables. – Peter Nov 07 '22 at 06:08
  • 5
    At the level of the machine, executing a load from address `90000001` would do one of two things. On some architectures, unaligned accesses are illegal so the instruction would trap and you'd get a segmentation fault or similar. On others, unaligned accesses are legal, and you'd get the integer represented by the four bytes starting at address `90000001`. Since your example machine appears to be big-endian, that would be the value `0000FFFF`, i.e. `65535`. Even when unaligned accesses are legal, they may be slower than aligned accesses. – Nate Eldredge Nov 07 '22 at 06:12
  • 3
    But at the level of C++, the other comments are quite right that this is simply undefined behavior, and even on a platform whose CPU architecture allows unaligned accesses, the C++ compiler may still mangle your code so that it behaves erroneously. – Nate Eldredge Nov 07 '22 at 06:12
  • 1
    See also [Dereferencing a pointer that has been assigned specific memory address](https://stackoverflow.com/questions/38044421/dereferencing-a-pointer-that-has-been-assigned-specific-memory-address) – Jason Nov 07 '22 at 06:14
  • You can, sort of, do this if you put the data into a C-compatible struct or array. Then you can copy the contents of that to a char buffer. Then you can examine the bytes in the char buffer as you see fit, including extracting 4 bytes starting from offest 1. – hyde Nov 07 '22 at 06:14
  • 1
    big-endian model, that's a rarity this days... – user3124812 Nov 07 '22 at 06:14
  • 1
    *"if I tried to dereference a pointer at the address `90000001`?"* -- how do you plan to get this address in the first place? Once you have a method for producing this address, it would be possible to see if the result is defined or undefined behavior. *Note: by pointer arithmetic, `(&sum)+1` would produce the address `90000004` because `int` is 4 bytes.* – JaMiT Nov 07 '22 at 06:15
  • Also useful: [Why do I get a random number when increasing the integer value of a pointer?](https://stackoverflow.com/questions/20736493/why-do-i-get-a-random-number-when-increasing-the-integer-value-of-a-pointer) – Jason Nov 07 '22 at 06:33
  • 1
    Note that the picture might be incorrect if the alignment requirements for `double` is 8, which is typical for modern architectures. – Daniel Langr Nov 07 '22 at 07:07
  • @DanielLangr can you expand on what you mean by that? – Alec Mather Nov 07 '22 at 19:19
  • @AlecMather When `alignof(double)` is 8 (live demo: https://godbolt.org/z/8Tr8WG3xs), then the storage for each object of type `double` needs to be 8-byte aligned. Which means that its address must be divisible by 8, and this does not hold for `0x90000006`. – Daniel Langr Nov 07 '22 at 20:31
  • @DanielLangr got it. So the moral of the story here is... 1) it's UB, 2) there is only 1 valid address per variable, 3) don't do anything with the addresses that a variable is spread across...? – Alec Mather Nov 07 '22 at 20:53
  • @AlecMather AFAIK, working with a misaligned object is UB. I don't understand what you mean by _"valid address per variable"_. A variable has some address, and this is valid. You can do many things with the addresses of a variable storage, such as reading its binary representation (at least with trivially-copyable types). – Daniel Langr Nov 08 '22 at 07:26

0 Answers0