Regarding initialization, if one wants portable code that works for more than one machine+compiler version, it's advisable to program against the C++ virtual machine specified in the standard. This virtual machine does not contain a stack or heap.
Generally your comment strikes me as assuming that UB is some kind of error. In practice UB is more a promise the programmer made to never do certain things, allowing the compiler to assume that these things never happen.
How UB manifests is undefined. A program that has more than zero UB cannot be assumed to be memory safe because we can't make any general assumptions about its behavior because. UB is not specified to be localized it can manifest in any way, rendering all assumptions about the program moot. In practice when focusing on specific compilers and machines we can make reasonable localized assumptions, but these are always subject to change with every new compiler version.
Memory safety is certainly critical when it comes to exploits, but even in a setting without adversaries it's absolutely crucial for reliability and portability.
> In fact Rust also silently allows signed integer overflow.
Silently for release builds, and panic in debug builds. The behavior is implementation defined and not undefined, in practice this is a subtle but crucial difference.
Take this example https://cpp.godbolt.org/z/58hnsM3Ge the only kind of UB AFAIKT is signed integer overflow, and yet we get an out-of-bounds access. If instead the behavior was implementation defined the check for overflow would not have been elided.