Is reading from a random address safe? I know writing is undefined behaviour but how about reading only?
Well, in many visual debuggers, I can see the contents of the memory in an arbitrary address. How is this done?
Since the behavior is undefined, the answer is undefined - or at the very least, erratic.
If you get lucky and the random address is within the memory bounds of your program, it would be fine to read most likely and you'd just get random junk.
If it's outside of the scope, (i.e. 0x0/NULL), you'd most likely get a segmentation fault (although again, this isn't guaranteed) which would terminate your program - if you'd consider this "safe" then yes, otherwise no.
No, it is not safe. Even if you don't care about the value being defined or accurate, there is such a thing as memory mapped IO, so a random address could interact with peripheral hardware. I did that in the days before protected memory, and yes, it can bring down the system.
Nowadays, depending on your system, I'd expect to see a segfault for addresses outside your process space. Without that protection, a bad app could access valuable data, like passwords, credit card info, etc. when used in a good app.
Also, addresses you see in the debugger are likely not real, physical addresses. Instead, you probably only see virtual memory addresses.