Может ли этот простой код C # привести к переполнению стека? - PullRequest
0 голосов
/ 10 февраля 2009

У меня есть библиотека классов, которая в основном записывает строку в текстовый файл. Одним из его методов является LogString (string str), так что мне просто интересно, основываясь на приведенной ниже функции, если я вызываю ее много раз, например, более 600 раз, вызывает ли это стекопоток?

    public void LogString(string str)
    {  
        try
        {
            if (filePathFilenameExists())
            {
                using (StreamWriter strmWriter = new StreamWriter(filePathFilename, true))
                {
                    strmWriter.WriteLine(str);
                    strmWriter.Flush();
                    strmWriter.Close();
                }
            }
            else
            {
                MessageBox.Show("Unable to write to file");
            }
        }
        catch (Exception err)
        {
            string errMsg = err.Message;
        }

    }

Ответы [ 13 ]

0 голосов
/ 10 февраля 2009

Вызов этой функции не приведет к «переполнению стека». Вы можете вызвать переполнение стека только рекурсивно вызывающей функцией. Я кратко объясню:

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

Итак, перед вызовом вашей функции у вас может быть в стеке:

.                           .
.                           .
.                           .
|                           |
+---------------------------+
| performComplexOperation() |
| return address            |
| local variables           |
| ...                       |
+---------------------------+

Затем вы вызываете функцию LogString:

.                           .
.                           .
.                           .
|                           |
+---------------------------+
| performComplexOperation() |
| return address            |
| local variables           |
| ...                       |
+---------------------------+
| LogString()               |
| return address            |
| local variables           |
| ...                       |
+---------------------------+

Но после завершения LogString код вернется к performComplexOperation с использованием обратного адреса. Запись для LogString будет удалена:

.                           .
.                           .
.                           .
|                           |
+---------------------------+
| performComplexOperation() |
| return address            |
| local variables           |
| ...                       |
+---------------------------+
       (this is where
    LogString used to be)

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

* Не совсем, но достаточно близко.

0 голосов
/ 10 февраля 2009

В ответ на обновление OP : проблема, вероятно, связана с методом caller , а не с самим LogString(). Если вызывающий метод действительно является рекурсивным, то, безусловно, существует риск переполнения стека, если выделенный размер стека недостаточно велик.

0 голосов
/ 10 февраля 2009

Вы спрашиваете , если это вызовет переполнение стека или почему оно вызывает переполнение стека?

Переполнение стека (обычно) происходит, когда рекурсия идет не так, как надо.

...