You have excellent tooling (*sanitizer, static analysis, valgrind, ${WHATEVER}) and abstractions provided to do handholding for you (ie. unique_ptr).
Most of that was created in last few years.
Lint was created in 1979, during the mid-90's we already had Insure++, Purify and others, ages before of the free beer alternatives.
Yet being free still doesn't help the large majority of C and C++ to actually use them, as proven at one of CppCon talks, where a tiny 1% of the attendees confirmed using any kind of analysers.
Your -second- third paragraph is, unfortunately, still correct though.
Maybe they are so skilled the need does not arise?
Belief that you are skilled enough to write C/C++ code that doesn't exercise undefined behavior either shows that you don't know what is undefined behavior or that you believe you are the best programmer to have ever lived.
As for how well, usually conferences like CppCon have the top of the tops.
https://events.linuxfoundation.org/wp-content/uploads/2017/1...
There hasn't been much in terms of changes. Languages immune to classes of vulnerabilities by default and/or sound checkers that can catch all of them seem necessary. And by seem necessary, I mean massive, empirical evidence that most developers can't code safely without such alternatives even on critical, widely-used, well-funded projects.
Even if I don't touch those languages for production code, my whole stack safety is dependent how well those underlying layers behave, and how responsibile the developers were towards writing secure core.
Which as proven by buffer oveflows in IoT devices not much.
Pascal was replaced by Java and C#.
NDAs make us not able to tell about stuff.
What magic variant of C or C++ compiler are you using that throws errors on buffer corruption, unless you are speaking about using code with debugging mode enabled in production instead of using a proper release build.
If you use high-level arrays with bounds-checking, which are not always fast enough, and can become a maintenaince burden. If they should be absolutely secure (like, std::vector isn't - it can be moved behind your back), they also require GC.
To make matters worse, compilers, ever searching for diminishing returns on performance improvements, have been steadily making the CONSEQUENCES of UB worse, to the point that even debugging is getting harder and harder. These languages are unique in their growing user hostility.