Распределение стека может дать сбой , и вы ничего не можете с этим поделать.
В современной ОС значительный объем памяти будет выделен для стека для начала (в Linux оно кажется 128k или около того) и a (обычно намного больше, например 8M) в Linux, и обычно настраиваемый) диапазон виртуальных адресов будет зарезервирован для роста стека. Если вы превысите зафиксированную часть, фиксация большего объема памяти может завершиться ошибкой из-за нехватки памяти, и ваша программа вылетит с SIGSEGV
. Если вы превысите зарезервированный диапазон адресов, ваша программа определенно потерпит неудачу, возможно, катастрофически, если она закончит перезаписью других данных чуть ниже диапазона адресов стека.
Решение не состоит в том, чтобы делать безумные вещи со стеком. Даже начальная сумма в Linux (128 КБ) занимает больше места в стеке, чем вы когда-либо должны использовать. Не используйте рекурсию вызовов, если у вас нет логарифмической привязки к количеству уровней вызовов, не используйте гигантские автоматические массивы или структуры (включая те, которые могут быть результатом измерений VLA, предоставленных пользователем), и у вас все будет хорошо.
Обратите внимание, что не существует переносимого и безопасного для будущего способа измерения текущего использования стека и оставшейся доступности, поэтому вы просто должны быть в этом уверены.
Редактировать: Одна гарантия, которую у вас есть, о распределении стека, по крайней мере в реальных системах (без взлома сплит-стека), состоит в том, что пространство стека, которое вы уже убедились, у вас не будет волшебным образом исчезают. Например, если вы успешно один раз позвонили c()
из b()
из a()
из main()
, и они не используют никаких VLA, которые могут различаться по размеру, второе повторение этого же шаблона вызова в том же экземпляре ваша программа не подведет. Вы также можете найти инструменты для выполнения статического анализа в некоторых программах (программы без излишнего использования указателей функций и / или рекурсии), которые определят максимальный объем стекового пространства, когда-либо потребляемый вашей программой, после чего вы можете настроить проверку при запуске программы. что вы можете успешно использовать столько места, прежде чем продолжить.