Повреждение памяти

Повреждение памяти — ситуация, возникающая в программе, когда содержимое адресов памяти непреднамеренно изменяется из-за программных ошибок. Это явление также известно как нарушение безопасности памяти. Использование повреждённых данных из памяти в дальнейшем может привести к аварийному завершению программы или её непредсказуемому поведению. Около 10 % аварий приложений в системах Windows связано с повреждением стека[1].

Современные языки программирования такие, как C и C++, предоставляют мощные средства явного управления адресами памяти и арифметики указателей. Они предназначены для разработки эффективных приложений и системного программного обеспечения. Однако неправильное использование этих возможностей часто приводит к ошибкам, связанным с повреждением памяти.

Повреждение памяти относится к одному из самых трудноустранимых видов программных ошибок по двум причинам:

  1. Источник повреждения памяти и проявление ошибки часто значительно разделены, что затрудняет установление причинно-следственной связи.
  2. Симптомы ошибки проявляются при необычных условиях, поэтому воспроизвести проблему стабильно зачастую сложно.

Классификация

Ошибки повреждения памяти подразделяются на четыре категории:

  1. Использование неинициализированной памяти: содержимое неинициализированной памяти считается мусором, и использование таких значений приводит к непредсказуемому поведению программы.
  2. Использование памяти «без владельца»: часто для доступа к памяти используются указатели. Если указатель является нулевым, висячим (указывает на уже освобождённую память) или ссылается на область памяти вне текущего стека или его границ, то программа обращается к памяти, которой уже не владеет. Такие указатели — серьёзный программный дефект. Доступ к такой памяти обычно вызывает исключения операционной системы, известные также как страничные сбои, что приводит к аварийному завершению программы.
  3. Использование памяти за пределами выделенного объёма (переполнение буфера): если массив используется в цикле с ошибочными условиями, возможно обращение и изменение памяти за пределами границ массива. Переполнения буфера — один из наиболее часто эксплуатируемых видов ошибок компьютерными вирусами[2], что вызывает серьёзные проблемы информационной безопасности (например, атака возврата в библиотеку) в используемых программах. Ошибки могут возникать и при обращении к памяти до начала буфера.
  4. Ошибки управления памятью кучи: среди наиболее распространённых ошибок — утечки памяти и освобождение памяти, не относящейся к куче или не выделенной программой.

Защита

Существуют различные средства для обнаружения ошибок повреждения памяти, такие как Purify, Valgrind, Insure++, AddressSanitizer[3] и другие.

Примечания

  1. Application Verifier (англ.). MSDN Library. Microsoft (19 апреля 2011). Дата обращения: 16 июня 2024. Архивировано 21 апреля 2012 года.
  2. Attack Vector: Buffer Overflows Top Threat (англ.). ISSSource. Дата обращения: 27 апреля 2026. Архивировано 1 октября 2012 года.
  3. AddressSanitizer, a fast memory error detector (англ.). Дата обращения: 27 апреля 2026. Архивировано 15 мая 2015 года.

Категории