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

    @res2001
    Developer, ex-admin
    Посмотрите на код ниже:
    char a[5];
    int b = 0;
    a[5] = 'a';

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

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

    Для поиска подобных ошибок обычно используют инструменты типа valgrind memcheck
    Ответ написан
    Комментировать
  • Чем опасно переполнение статического массива в C?

    @zedxxx
    Да всё тем же. В стеке лежат некие данные (указатели, переменные, адреса возврата) и переполняя массив, вы тем самым затираете эти данные мусором.

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

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

    Если в buffer2 писать сверх выделенного размера, то будут затёрты все данные, что лежат под ним.
    Ответ написан
    Комментировать
  • Столкнулся со странным утверждением в книге по C. Так какой же адрес у переменной массива?

    wisgest
    @wisgest
    Не ИТ-специалист
    array == &array[0]
    &array численно равен array, но имеет другой тип.
    Ответ написан
    Комментировать
  • Какие есть книги по Bash?

    piromanlynx
    @piromanlynx
    Системный администратор в Perfect Solutions
    Я вот люблю доки: www.gnu.org/software/bash/manual/bash.html
    Ответ написан
    Комментировать
  • Чем отличается HAVING от WHERE?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега SQL
    Седой и строгий
    Из документации:
    Основное отличие WHERE от HAVING заключается в том, что WHERE сначала выбирает строки, а затем группирует их и вычисляет агрегатные функции (таким образом, она отбирает строки для вычисления агрегатов), тогда как HAVING отбирает строки групп после группировки и вычисления агрегатных функций. Как следствие, предложение WHERE не должно содержать агрегатных функций; не имеет смысла использовать агрегатные функции для определения строк для вычисления агрегатных функций. Предложение HAVING, напротив, всегда содержит агрегатные функции. (Строго говоря, вы можете написать предложение HAVING, не используя агрегаты, но это редко бывает полезно. То же самое условие может работать более эффективно на стадии WHERE.)
    Ответ написан
    Комментировать