"Dereferencing a bad pointer results in undefined behaviour".
How can it be undefined behaviour if it generates a runtime error time
and time again?
It does, or it does not. It depens on the situation. In your code, on
your system (or your "class" of systems), compiled with your (version
of the) compiler, it generates "runtime error". It can be __completely
different__ somewhere else.
Here's why (but we are stepping completely out of the land of anything
guaranteed by C and C++ languages)...
When you write int* pi in a function, pi is placed on the stack of
your main. It is not initialized (because you didn't do it), and hence
has value of whatever was in memory. And that means __whatever__. Any
integral value size of a pointer is possible. So your pi points to any
memory location possible. It may point to memory that belongs to your
code, or that does not belong to it. There is __no guarantee
whatsoever__. Hence the undefined behavior.
I have to press you here: you must understand C language better first.
Forget C++ and exceptions. Understand handling memory in C. Understand
what does it mean "undefined behavior". Once you do that, answer to
your question will be evident (and will pretty much be what people
here are telling you).
Goran.