Вопрос

Я даже не знаю, что вызвало это в моем приложении.Что это такое?Я создал новый экземпляр класса (класс был в другом файле), но при первом вызове метода он выдает исключение StackOverflow.

Единственное, что, по моему мнению, логично вызвало бы исключение stackoverflow, это если бы кто-то проголосовал против Джона Скита.

Но теперь серьезно, в чем дело?Я обошел это, создав другой класс в том же файле, что и первый класс, и используя его для вызова методов для меня.

Это было полезно?

Решение

Как правило, исключение переполнения стека вызвано рекурсивным алгоритмом, в котором глубина рекурсии превысила (обычно) фиксированный предел стека.Обычно это результат ошибки в алгоритме, но это также может быть вызвано тем, что структура данных, к которой вы применяете алгоритм, слишком "глубокая".

Вот тривиальный пример ошибочной рекурсии (без какого-либо конкретного PL).

function int length(list l) {
    if (empty(l)) {
        return 0;
    } else {
        return 1 + length(l);  // should be 'return 1 + length(tail(l));
    }
}

Вызов длины для любого непустого списка приведет к переполнению стека на типичном языке программирования.Но даже если вы исправите ошибку, вызов метода для длинного списка, скорее всего, вызовет переполнение стека.

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

Другие советы

Исключение stackoverflow возникает, когда вы превышаете выделенный размер стека, обычно это происходит из-за рекурсивного вызова методов и никогда не завершается, это также может быть вызвано различными непонятными цепочками методов.Проблема в том, что у вас, вероятно, есть что-то в объеме следующего в объекте.

void MyMethod()
{
    MyMethod();
}

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

P.S.SO был назван в честь конкретного исключения, о котором идет речь (это фундаментально и не ограничивается .NET), это просто умное название для сайта разработчика.

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

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

Стек - это место, где компьютер хранит список вызываемых в данный момент функций, а также используемых переменных и параметров.Таким образом, если функция Main вызывает функцию A, а затем функция A вызывает функцию B, и они используют переменные c, d и e, стек будет содержать всю эту информацию.Однако стек не так уж велик.Итак, если функция B затем вызывает функцию C, которая вызывает функцию D...и т.д., в конечном итоге получая сотни вложенных функций, в конечном итоге стек "переполнится" - не хватит места для хранения другого вызова функции.

Как отмечали другие люди, это обычно происходит с рекурсивной функцией (где функция B вызывает функцию B, которая затем вызывает функцию B ...) - в конечном счете, стек переполнится.Вам нужно будет найти, где вызывается эта рекурсивная функция и почему она не выходит из рекурсивного цикла, когда это предполагается.

Конечно, проблема может заключаться не в том, что это ошибочный рекурсивный алгоритм - возможно, просто количество вызовов функций превышает размер стека.Так что, если ваш алгоритм потенциально может вызвать рекурсивную функцию несколько сотен раз, возможно, так оно и есть.

Обычно это вызвано рекурсивным вызовом функции, где этот рекурсивный вызов никогда не завершается.Вы можете получить это несколькими способами.Одним из способов может быть рекурсивный алгоритм без базового варианта, другим распространенным является создание объектов A и B, которые создают друг друга в своих конструкторах, и т.д.

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

Недавно я портировал старое приложение VB6 на VB.NET, которое использовало чудовищную рекурсивную функцию для сортировки одинаково большого объема данных.Алгоритм был в порядке, но выполнение постоянно вызывало ошибку переполнения стека.После долгой возни я понял, что VB творит слишком много волшебства за этим кодом:простое литье типов имеет свою цену.Таким образом, рекурсивная функция слишком сильно полагалась на позднюю привязку вместо использования переменных типа, и это привело к ОГРОМНОМУ количеству приведений, синтаксического анализа и т.д.накладные расходы (одна строка кода может вызывать от 2 до 10 функций ...), которые, очевидно, приводили к переполнению стека.

TL; DR:Используйте DirectCast() и статическую привязку (типизированные переменные), чтобы предотвратить переполнение стека VB во время выполнения рекурсивной функции.

У меня возникла эта проблема, я заметил, что неправильно ввел lstEncounter.Как я узнал из моего класса C ++, проблема заключается в рекурсивном алгоритме, который в основном вызывает сам себя с теми же параметрами.Мой пример, где я получил ошибку:

Property Encounter(ByVal N As Integer)
    Get
        If N < lstEncounters.Count Then
            Return Encounter(N)
        Else
            Return Nothing
        End If
    End Get
    Set(value)
        lstEncounters(N) = value
    End Set
End Property

У меня возникла ошибка Stackoverflow.Я использовал процедуру, которая добавляла 1 к счетчику, а затем повторно вызывала ту же процедуру.Примерно через каждые 2500-3000 циклов я получал ошибку stackoverflow.Я добавил DO...Цикл, который вызывает процедуру, я использую VB Express:

ДО ТОГО , КАК:

Public Sub mainloop()

Dim cntr as integer

If cntr >= 5000  ( I just picked a number at random)

    me.close  ( I close the program)

...               (This is where I would manipulate the cntr for diff 
results)

cntr = cntr + 1  ( increment the cntr)

mainloop()        (re call my loop) 

End IF

End Sub

(как я уже говорил ранее, примерно через 2500-3000 я получу ошибку Stackoverflow)

ПОСЛЕ:(Поместите это для выполнения в первую очередь)

Dim LoopCntr as integer

Do While LoopCntr <= 40000  (this my number.. Use your own number)

If LoopCntr > 40000 Then

        Exit Do
End If

mainloop()       (The mainloop() has not been changed just the method of calling it)
LoopCntr = LoopCntr + 1

Loop

me.close        (When LoopCntr reaches max it closes the program)

(После добавления цикла Do .. моя программа выполнялась 40000 раз без "Stackoverflow")

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top