StackOverflowException в c #, когда нет локальной переменной в функции - PullRequest
3 голосов
/ 20 марта 2012

когда я делаю это

static void Main()
{
   Main();
}

я получаю исключение stackoverflow.Как я уже читал о C #, они говорят, что ТОЛЬКО локальная переменная типов значений (и недолговечных) пойдет в стек.

Но здесь в коде нет локальной переменной, чтобы перейти в стек, что переполняет ее?

Я знаю из строки кода сборки Перспектива, что ссылка на Main () тоже пойдет по стеку?Это правильно ?

Ответы [ 7 ]

3 голосов
/ 20 марта 2012

Каждый раз, когда вы вызываете main (), адрес возврата сохраняется в стеке, что в конечном итоге приведет к взрыву вашего стека

2 голосов
/ 20 марта 2012

Когда вы вызываете функцию, вы должны помнить, куда вернуться, когда завершился вызов функции.

Этот обратный адрес хранится в стеке, поэтому вы получаете переполнение стека с вашим кодом.

Из документации :

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

2 голосов
/ 20 марта 2012

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

2 голосов
/ 20 марта 2012

Кадр стека помещается в область действия Main, даже если он «пустой».Кроме того, как заявили другие, он включает в себя обратный адрес.Так что да, вы правы.

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

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

Возможно, вы пытаетесь попробовать что-то вроде реализации сопрограммы в C #.К сожалению, язык не предлагает поддержки для этого в прямом смысле этого слова (Аксум привык, потому что он использовал связанные стеки).Хотя, тем не менее, я еще не видел, чтобы он пытался использовать новую поддержку продолжения C # 5.

1 голос
/ 20 марта 2012

Stackoverflow

У Джона Скита есть хорошее объяснение того, почему это происходит.

(..) это будет выдвигать новый кадр стека для каждого рекурсивного вызова Foo, и эти кадры стека никогда не будут вытолкнуты, так как вызовы фактически никогда не вернутся.

Теперь просто замените Foo на Main.

1 голос
/ 20 марта 2012

Это вызовет бесконечный цикл, поэтому вы получите исключение stackoverflow.

0 голосов
/ 20 марта 2012

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

...