For a taste of how common undefined behaviour is, even in important code bases, (and why everybody should be using tools to test for it) see this post: http://blog.regehr.org/archives/1054 "Integer Undefined Behaviors in Open Source Crypto Libraries"
Also the follow up about how difficult C sometimes makes it to avoid undefined behaviour without a performance penalty: http://blog.regehr.org/archives/1063 "Safe, Efficient, and Portable Rotate in C/C++"
Perhaps this will help find these coding mistakes? (unfortunately, it seems to be a runtime checker and not a compile-time warning)
But sooner or later you'll come across a programmer who isn't aware of wrapping and wrongly assumes the value can only grow when a positive integer is added to it. So you could define a language which silently does bignums and all is well, except now you have to deal with memory allocation (this can be a major issue on memory-constrained platforms) during integer arithmetic, and the way bignum computations affect the program's performance & timing (crypto side channel attacks anyone?). So the next programmer again has to know the pitfalls of the Defined behavior and Do The Right Thing, just as he must do now with Undefined Behavior (i.e. rearrange bounds checking and pointer arithmetic so that it'll never point beyond one past the last element of an array; and so that your signed integers never overflow).
The second snippet (pointer dereference before NULL check) is perhaps more subtle, and again I might agree that the language would be safer if it didn't allow the removal of the NULL check that would keep this incorrect code from doing further harm. However, no matter what your proposed defined behavior for NULL/invalid pointer dereferencing is (what would it be? I have no idea), there would likely be cases where the programmer makes the wrong assumption and his program relying on that Defined behavior is still incorrect and potentially insecure.
Simply defining undefined behavior just doesn't fix incorrect code. You still have to remove the broken (undefined or not) code from the codebase...
EDIT: If you meant to suggest languages whose compiler will abort if it finds code that might result in undefined behavior, well, that's much harder. UB in C is predominantly a run-time issue, so you'd be making a really smart static analyzer to detect at compile time whether your code can actually hit UB. Did someone solve the halting problem? Alternatively you can make a language where integers never overflow. Then we get to what I said about bignums and surprise-allocation and such.. Haskell just isn't for everything.
In the Java memory model you still get memory-safety in the presence of race conditions, but other than that the program behavior is pretty much undefined. It's better than undefined behavior in C, but not by much.
I assume everyone reading a discussion about undefined behavior knows what nasal demons are, but just in case someone doesn't: in illustrating just what "undefined behavior" means in C, it has been suggested that it would be perfectly legal for a compiler, upon encountering such, to cause demons to fly out of the programmer's nose. The point being that it's not just a matter of producing an unexpected value or something of that nature, but a completely unexpected behavior. As a real-world example, early versions of gcc would, upon encountering a #pragma (whose behavior is undefined) would start a game of nethack.
I know that sounds a bit like a cop out, but it lays the finger on the pain point of modern computing, that whatever we do, we are still so heavily reliant on C for everything low level.
How would we come close? I'd say name a language whose JIT directly outputs (x86) assembly, and whose runtime is written in a runtime free version that is output by that same JIT.
The only language I know of that can do that atm is Rust.
And with intelligent coding you could probably get those checks to be very minimal.
For the sort of code that was best written in C, a few decades ago, it was often reasonable engineering to depend on technically undefined behavior. Then over the decades the compilers made increasingly-subtle transformations without getting much better at telling you where they might have tripped you up (again, maybe except for clang which I haven't tried yet).