Как создать бесконечную рекурсию, которая будет генерировать исключение переполнения стека?

Я пытаюсь создать исключение переполнения стека с помощью следующей программы:

void f(int a) {
cout << a << ", ";
f(++a);
}

int main () {
f(0);
return 0;
}

Когда я запускаю эту программу, мой компьютер работает около 261824 call stack тогда command terminated Произошла ошибка во время выполнения. Теперь я хочу знать:

  1. Это хороший пример переполнения стека? если да, то почему command terminated ошибка произошла?
  2. Как я могу try, catch исключение переполнения стека?
  3. У меня много свободной памяти; почему мой стек не использует всю мою память?
  4. Как я могу определить размер стека, соответствующий моему call stack?

2

Решение

  1. Да, это переполнение стека. Получаемое сообщение об ошибке зависит от платформы, поэтому, если вы запустили его на другом типе компьютера, вместо этого может появиться «переполнение стека».
  2. Там нет хорошего портативного способа сделать это, как видел здесь. Это потому, что вы не получаете выброшенное исключение, вы получаете ОС, убивающую ваш процесс любым желаемым способом.
  3. Ваше ограничение стека намного меньше, чем ваша доступная память (обычно 8-20 МБ для стека). В определенных настройках ОС вы можете перенастроить это значение, если вам действительно нужно большее значение (ulimit -s 100000 в Solaris устанавливает его в 100 МБ). Но обычно превышение лимита стека означает, что вы делаете что-то не так. Небольшой лимит стека помогает ОС в схемах выделения виртуальной памяти и является ранним ловцом ошибок при переполнении стека (представьте себе более медленную версию вашего кода, потребляющую всю доступную память в течение часа или двух … не так весело для всего, что работает).
  4. Это может зависеть от ОС или компилятора и не является тем, что встроено в C ++. Пытаться эта ТА ссылка о различных подходах к определению размера стека.
4

Другие решения

Это все детали реализации. Технически реализация C ++ не должна иметь стек, она просто нуждается в автоматическом хранении. Существует по крайней мере одна реализация C, которая использовала связанные списки в куче (ну, в некотором роде — насколько я понимаю, это странная система) для их автоматического хранения.

Но, как правило, стек представляет собой непрерывную область адресного пространства памяти, которую процесс резервирует только для хранения автоматических переменных и фреймов вызовов. Он должен быть зарезервирован до того, как что-либо еще произойдет, потому что он должен быть смежным, и если какой-то кусок памяти будет выделен для другой цели, стек не сможет расти.

Если бы вы хотели использовать все адресное пространство памяти для стека, не было бы места для кучи (иначе, бесплатное хранилище). Таким образом, стек не использует всю память …

1 МБ — это традиционное значение для установки стека: немногие программы действительно нуждаются в большем количестве даже при скромном избегании размещения больших объемов данных в стеке. В многопоточных средах каждый поток имеет свой собственный стек: поэтому его небольшой размер также делает потоки дешевле. Современные системы, вероятно, устанавливают его больше, потому что у них много адресного пространства для каждого процесса.

В 64-битных системах было бы относительно легко использовать 50-битное адресное пространство для стека (гораздо больше, чем ваш компьютер в настоящее время может обрабатывать: центры обработки данных Google работают с петабайтами). Но недостатком этого является то, что вы отрываете свой стек только во время отладки. после Виртуальная память всей вашей системы была захвачена этим одним процессом. Плюсы к этому не так уж велики.

Размер стека определяется реализацией и не предоставляется стандартом C ++. Обратитесь к документации вашего компилятора, чтобы узнать, как определить, насколько он велик, и как изменить его размер.

Стандарт C ++ не предписывает, что происходит, когда вы разбиваете стек. В целом, когда стек перегружен, у вас, вероятно, будут серьезные проблемы: пишите код, чтобы он не происходил, а не перехватывали его после того, как это произошло.

6

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector