По идее сегфолт должен быть уже на строчке gamma [8] = -2; Но программа выполняется фактически до конца!
Если же предположить, что gcc использовал оптимизацию и в printf подставлял сразу констаты, то непонятно откуда сегфолт.
Что за фигня?
При обращении к отсутствующим элементам были переписаны поверх какие-то другие данные, относящиеся к программе, и обнаружилось это при выгрузке программы из памяти. В принципе, картина достаточно стандартная.
При записи gamma[8] = -2 вы просто перезаписали часть стека - никакого сегфолта тут не будет. А вот при завершении функции как раз сегфолт и вылезет - например при этом был перезаписан адрес возврата и управление будет передано неизвестно куда.
Проверять границы, valgrind memcheck и другие средства.
Это-то понятно.
Непонятны условия возникновения сегфолта. Просто я уже несколько раз ловил и исправлял в FOSS проектах сегфолты, связанные как раз с выходом за границы. Причём gdb по bt точно показывал место ошибки. Чем же тот выход за границу отличался от моего?
Непонятны условия возникновения сегфолта. Просто я уже несколько раз ловил и исправлял в FOSS проектах сегфолты, связанные как раз с выходом за границы. Причём gdb по bt точно показывал место ошибки. Чем же тот выход за границу отличался от моего?
Ну, давайте посмотрим что вообще такое ошибка сегментации - это попытка записи(чтения, исполнения) в(из) память, где данная операция недопустима. Соответственно поведение когда возникнет и возникнет ли сегфолт вообще очень сильно зависит от расположения участка в памяти, что рядом лежит, насколько далеко выход за границы происходит и т.д. В случае стека и незначительного выхода за границы чаще всего страдают либо соседние переменные, либо адрес возврата, либо переменные вызвавшей функции. При значительном отклоненнии (gamma[8000]=-2) сегфолт сразу будет. Если в динамической памяти, то там как получится. Статическая память - либо другую статическую переменную (без сегфолта, если переменная доступна для записи) либо в RO секцию обычно попадаем (тут сегфолт при записи будет сразу).
Решил проверить этот пример у себя. Собственно, сегфолт меня не удивляет -- тут уже описали причины, по которым он может возникнуть. Меня удивляет другое:
Почему компилятор, несмотря на -Wall ничего не говорит о присвоении значений элементам с номерами на 2 больше, чем можно?
И, кстати, когда вынес объявление gamma из блока main, то тогда никакого сегфолта не происходит. Правда, компилятор стал ворчать, что "встроенная функция gamma объявлена как не-функция. Заменил gamma на gama -- программа отработала без проблем (это меня не удивило)
P.S. Сделал ещё одну проверку: при компиляции указал оптимизацию.
При ключах -O2 и выше компилятор стал ворчать: warning: array subscript is above array bounds
Без -O и с -O0 и -O1 транслирует молча