Если рекурсия LP не разрешена, то могут быть случаи переполнения стека? - PullRequest
4 голосов
/ 21 июня 2011

Связано ли исключение «переполнение стека» только с использованием рекурсии? В каком другом контексте мы можем дать это исключение?

Ответы [ 5 ]

4 голосов
/ 21 июня 2011
  1. выделение локальных переменных, которые слишком велики для размещения в стеке, например, массив с миллионом элементов в стеке 64 КБ.
  2. слишком глубокий стек вызовов, даже без рекурсии, если каждыйподпрограмма имеет много локальных переменных.пример: a () вызывает b () вызывает c () ... вызывает z () вызывает a1 () ... вызывает z99 ().Локальная переменная каждой подпрограммы, а также адрес возврата для каждой функции (и, возможно, средства защиты от разрушения стека) остаются в стеке, пока стек не раскручивается при выходе из каждой функции.
3 голосов
/ 21 июня 2011

Если вы размещаете огромные буферы в стеке, используя динамические массивы C99. т.е.

void stackkiller(int size) {
  char toohuge[size];
  printf("Don't call this with too big an argument!\n");
}
2 голосов
/ 21 июня 2011

Поскольку любой рекурсивный алгоритм можно превратить в итеративный и наоборот, вот алгоритм переполнения стека в C99:

void stackoverflow()
{
    for (size_t n = 0; ; n *= 2)
        char a[n];
}

(Отключить оптимизацию компилятора.)

1 голос
/ 21 июня 2011

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

Многие языки допускают произвольно глубокую рекурсию / вызовы с помощью оптимизации хвостовых вызовов.Некоторые языки, такие как ML и Haskell, будут внутренне преобразовывать некоторые (когда вызов находится в конце вызывающей функции) функции / рекурсивные вызовы, чтобы избежать использования дополнительного пространства в стеке, таким образом позволяя эффективно бесконечную рекурсию.Идея заключается в том, что если вызов находится в самом конце вызывающей функции, пространство стека вызывающих функций больше не требуется и может быть возвращено для использования вызываемой функцией.

1 голос
/ 21 июня 2011

Если в стеке выделено слишком много памяти (например, см. В компиляторе VS ).

...