mr-Evan
@mr-Evan

Чем опасно переполнение статического массива в C?

Изучаю Си.
Как всегда, тема с памятью вызывает много вопросов.

Что на данный момент усвоено:
Массив можно объявить в
стеке:
char a[5];
и в куче
char *a = malloc(sizeof(char) * 5);

Знаю что запись за пределами динамического массива не сулит ничего хорошего (потому VS и ругается).
Об этом собственно и пишется везде.

Чем может грозить переполнение массива в стеке?
  • Вопрос задан
  • 277 просмотров
Решения вопроса 1
@zedxxx
Да всё тем же. В стеке лежат некие данные (указатели, переменные, адреса возврата) и переполняя массив, вы тем самым затираете эти данные мусором.

Нашёл красивую картинку, которая наглядно объясняет, как лежат данные в стеке:

5df9288163d6c761119182.png
Взял тут: Stack Canaries with GCC: Checking for Stack Overfl...

Если в buffer2 писать сверх выделенного размера, то будут затёрты все данные, что лежат под ним.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@res2001
Developer, ex-admin
Посмотрите на код ниже:
char a[5];
int b = 0;
a[5] = 'a';

И ответьте на вопрос:
1.Куда произойдет запись в последней строке?
2.Программист действительно хотел именно этого?
Учитывая, что память под стеком уже выделена ОС, то никакой ошибки при этом не происходит. Ошибка проявится где-то дальше по ходу выполнения программы, где будет использовано значение переменной b или производных от нее. Отловить подобные ошибки бывает достаточно трудно, т.к. причина ошибки и место проявления ошибки может быть сильно разнесено по коду.

С динамической памятью все примерно то же самое, за исключением того, что теоретически выделяется только запрошенное количество памяти, поэтому выход за пределы сразу же вызовет аппаратное исключение.
Но практически это обычно не так, т.к. обычно ОС выделяет память минимум в 4Кб (размер страницы памяти), а дальше выделенная память поступает в распоряжение менеджера памяти (malloc/free). Поэтому будет ошибка или нет зависит от реализации менеджера памяти, от количества выделяемойпамяти и т.п.
Если не произойдет исключения, то возможно повредятся (перезапишутся) данные менеджера памяти и дальнейшие операции с памятью будут не правильными. К чему это может в итоге привести - трудно предугадать, но ясно, что ни к чему хорошему.
Так же возможно, что никакие данные не повредятся, это вероятно еще хуже - вы думаете что программа работает нормально, но в дальнейшем вносите изменения в код и все разваливается хотя вроде бы изменения корректные. Убираете изменения - все опять хорошо. Вы думаете, что проблема в изменениях, а на самом деле нет.

Для поиска подобных ошибок обычно используют инструменты типа valgrind memcheck
Ответ написан
Комментировать
solotony
@solotony
покоряю пик Балмера
тем что ты запишешь что-то поверх "хороших" данных и испортишь их
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы