C++ type system allows invalid code (that uses freed or uninitialized memory) to run and just do weird incorrect things.
Type systems are decidable and thus cannot, by definition, rule out all errors. Instead, they look at a subset of possible errors. This subset is provably eliminated from valid code. "Dynamically typed" languages reduce that subset to the empty set.
There's also something about 'soundness' one could say.