Насколько критичной проблемой для программиста является ручное управление памятью, которое называют недостатком языка Си?
Неосвобожденная память (утечка памяти) - это самое безобидное, что может произойти.
- Сделать free дважды - это UB
- Забыли проверить результат malloc/calloc/realloc на не NULL, разыменовали - UB
- Почитали память, в которую ни разу не писали - UB
- Разыменовали указатель после free - UB
- Гонка данных - UB
- ...и еще дофига всего, от чего в лучшем случае программа просто будет работать неправильно, например спалит Ваш пароль, или переведет Ваши деньги на другой счет 10 раз.
Новый язык программирования Раст, как заявляют, лишен этого недостатка
Система типов Rust гарантирует лишь одно - в safe коде не будет UB. Утечка памяти, кстати, не является UB, поэтому память вполне себе можно утечь в safe коде, помимо циклических счетчиков ссылок std дает немало возможностей сделать это напрямую:
https://doc.rust-lang.org/beta/std/mem/fn.forget.html
https://doc.rust-lang.org/beta/std/mem/struct.Manu...
https://doc.rust-lang.org/beta/std/boxed/struct.Bo...
https://doc.rust-lang.org/beta/std/vec/struct.Vec....
но разве число ошибок в программе зависит именно от наличия или отсутствия ручного управления памятью
В Rust ручное управление памятью, как и в C и в C++, просто есть культура, что если некая структура аллоцировала память, то она ее освободит. Всякие Vec, Box и т.д. делают это в
Drop. В C++ многие повседневные типы так же освобождают в деструкторе память, которую они выделили. Однако в Rust есть разделение на safe и unsafe код и для прикладного программирования safe возможностей более чем достаточно. В C++ же весь код unsafe.
разве общее число ошибок не перераспределяется на другие недостатки программы
Нет, не перераспределяется. Хорошая система типов действительно может избавить от многих ошибок, что в целом сделает ПО более надежным. Но надо понимать, что от всех ошибок не избавит ни что. Банальная дискоммуникация с заказчиком порождает огромное число багов.
Но в Rust очень быстро привыкаешь к такому замечательному подходу в разработке, как Type Driven Development, который позволяет предупредить многие ошибки еще до написания кода. После Rust я стал применять этот подход и в других ЯП, и он работает очень хорошо, даже там, где типизация не такая строгая.
являются ли ошибки с памятью ошибками программиста, а не компилятора и языка программирования
Безусловно это ошибки программиста. Программисты, как правило, - это люди, а людям свойственно ошибаться. И хорошо, когда есть средства статического анализа, которые помогают предотвращать ошибки до выхода ПО в продакшн.
P.S. Вот интересная статья про Rust к прочтению:
https://steveklabnik.com/writing/a-sad-day-for-rust
И к чему она привела:
https://github.com/fafhrd91/actix-web-postmortem