Что нужно для написания безопасных для памяти приложений C ++?

Можно ли либо создать стандарт кодирования, либо использовать библиотеку, которая может быть доказана для устранения любых ошибок управления памятью в C ++?

Я думаю о чем-то вроде Java, просто невозможно, например, иметь висячие указатели в приложениях Java.

5

Решение

Можно ли либо создать стандарт кодирования, либо использовать библиотеку, которая может быть доказана для устранения любых ошибок управления памятью в C ++?

И да и нет.

Даже если вы используете очень строгий стандарт, это ограничит вас очень узким подмножеством языка C ++. Например, Power of Ten (Правила разработки критического для безопасности кодекса) говорит, что вы должны полностью отключить использование кучи. Однако это само по себе не останавливает вас от повреждения памяти.

Я думаю, что если бы был точный ответ на этот вопрос, отрасль решила бы это десятилетия назад, но мы здесь …

Я не верю, что есть определенный способ убедиться, что ваш код полностью безопасно, но есть лучшие практики что поможет вам убедиться в том, что проблем будет как можно меньше.

Вот некоторые предложения:

  • Как упоминалось ранее, полное запрещение использования кучи может быть поможет вам избавиться от всех проблем с управлением памятью, но это не решит проблему полностью, потому что это не спасет вас, например. блуждающий указатель пишет.
  • Я рекомендую вам прочитать о Правило трех, пяти и нуля которые объясняют некоторые вещи, о которых вам нужно позаботиться.
  • Вместо того, чтобы управлять памятью самостоятельно, используйте умные указатели, такие как shared_ptr, unique_ptr и т.д. Но, конечно, вы все равно можете злоупотреблять этим, если хотите. (Например shared_ptr не поможет, если у вас есть циркулярные ссылки …)
  • Используйте инструменты проверки памяти, такие как valgrind, который может помочь вам обнаружить проблемы и убедиться, что ваш код не содержит ошибок.

Даже если вы придерживаетесь любого стандарта кодирования или передового опыта, ошибки могут и будут иметь место. Никто не гарантирует, что вы будете в безопасности. Однако, следуя этим рекомендациям, вы можете минимизировать вероятность и влияние ошибок.

7

Другие решения

Можно ли создать стандарт кодирования или использовать библиотеку
что может быть доказано, чтобы устранить любые ошибки управления памятью в C ++?

Нет.

Но то же самое относится и к Java. Пока Java не делает технически допускают утечки памяти, они действительно (и другие утечки ресурсов) на практике, если вы не обращаете внимания.

Классический пример, который особенно хорошо известен в мире Android, — это когда коллекция экземпляров слушателя продолжает расти, чем дольше работает программа, потому что слушатели забывают отменить регистрацию. Это может быстро вызвать сотни МБ утечка в приложении с графическим интерфейсом, когда слушатель является экземпляром некоторого окна или класса представления, который хранит ссылки на большую графику. Поскольку вся эта память все еще доступна, сборщик мусора не может ее очистить.

Тот факт, что вы технически не потеряли указатель (он все еще находится в коллекции), совсем вам не поможет. Наоборот; это причина утечки, потому что она предотвращает сбор мусора.

В том же духе, что и выше, хотя Java технически не допускает висячих указателей, подобные ошибки могут привести к тому, что вы получите доступ к указателю на некоторый объект окна или представления, который все еще находится в допустимой области памяти для вашей программы, но которого больше не должно существовать больше не видно Хотя сам указатель доступа не вызывает сбоев или проблем, другие виды ошибок или сбоев (например, NullPointerException) обычно следуют достаточно скоро, потому что логика программы испорчена.


Так много за плохие новости.

Хорошей новостью является то, что оба языка позволяют уменьшить проблемы управления памятью, если вы следуете простым методические рекомендации. Что касается C ++, это означает:

  • Используйте стандартные коллекции (например, std::vector или же std::set) когда вы сможете.
  • Сделайте динамическое размещение вашего второго выбора. Первым выбором всегда должно быть создание локального объекта.
  • Если вы должны использовать динамическое распределение, используйте std::unique_ptr,
  • Если ничего не помогает, подумайте std::shared_ptr,
  • Используйте голый new только если вы реализуете некоторый контейнерный класс низкого уровня, потому что существующие стандартные контейнерные классы (например,std::vector или же std::set) не работают для вашего варианта использования. Это должно быть крайне редким случаем.

Также есть Boehm сборщик мусора для C ++, но я никогда не использовал это лично.

1

По вопросам рекламы [email protected]