This is a belief that many C++ programmers have, and having spent much of my life in the past few years finding ways to break a C++-like memory model (Rust) I cannot emphasize enough how dangerously wrong it is. Safer than C, sure. As safe as a memory-safe language like Java, absolutely not.
The safety you mentioned comes from only two things: type safety and runtime array boundary checks.
There is no problem in implementing runtime boundary check in C++.
What else in C++ is less safe than in Java? Is there some kind of magic?
Although it can be mitigated with specially written collections (incompatible with the standard collections) and strict coding guidelines, I have to agree with you that the C++ memory model itself is insanely dangerous.