Bopha
Bopha

Reputation: 3416

Could this simple C# code result in a stack overflow?

I have a class library that mainly logs the string to text file. One of its method is LogString(string str) so I'm just wondering based on the function below if I call it for many times like over 600 times, does it cause stackoverflow?

    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;
        }

    }

Upvotes: 0

Views: 844

Answers (13)

Bopha
Bopha

Reputation: 3416

Thanks you everyone for the inputs and sorry for the hustle. It was my fault because my program has recursion which I didn't know. The reason I didn't find that out because I didn't continue to trace the calls until the program stopped. I always stopped the debug when the last call was made to that last case scenario(last function) until last night I continued to debug until the program stopped itself then I saw there were many calls were made back and forth so based on my little programming experience I conclude that is recursion.

Upvotes: 0

Bopha
Bopha

Reputation: 3416

This is the function filePathFileNameExists that Sean thought was recursive.

    public bool filePathFilenameExists()
    {
        if (File.Exists(filePathFilename))
        {
            return true;
        }
        else
        {
           MessageBox.Show("Can not open Existing File.");
           return false;
        }
    }

Upvotes: 0

lubos hasko
lubos hasko

Reputation: 25052

No, it won't cause stack overflow but it can cause other exceptions if two different threads will try to write into the same file. consider using lock to make it thread-safe if necessary.

Upvotes: 3

Hamish Smith
Hamish Smith

Reputation: 8181

@Franci Penov offers good advice.
Please read this post by Raymond Chen.
It neatly explains why the function that the stack overflow exception is pointing to is not the culprit.

Upvotes: 2

JP772
JP772

Reputation: 73

I think Paul Fisher is right but this is my first post and I don't have the rep to comment on his answer.

The same theory in my words; your calling function is causing the stack overflow. It pushes copies of itself onto the stack until it's a relatively short distance from the end. On some "N-1"th recursive iteration of the calling function, the stack depth of your LogString is enough to cause the overflow, since you'd then be within a pretty short distance from the end of the stack. filePathFilenameExists() likely has a deeper maximum stack than most of the other methods in the calling function and is enough to single LogString out as the lucky guy who catches the exception.

Theory aside, your problem should be apparent by the output of LogString, assuming it's being called repetitively from somewhere. That and viewing your stack in the IDE debugger.

Upvotes: 0

lc.
lc.

Reputation: 116458

Something else is funny here because there's basically no way the code you've posted can cause a stack overflow.

  • What's the rest of your call stack look like when the stack overflow exception is thrown?
  • Is filePathFileName a field or a property? If it's a property, are you doing anything in your getter? Perhaps calling LogString(String) again?

Upvotes: 0

Franci Penov
Franci Penov

Reputation: 75991

If you realy want to find your culprit, you need to look a little bit deeper in the call stack and look what other functions are on it. More precisely, look for repetetive traces.

Another way to get the stack overflow exception is if your code allocates big chunk of memory on the stack. Do you happen to deal with big structures somewhere in your code?

Upvotes: 1

Bopha
Bopha

Reputation: 3416

    public bool filePathFilenameExists()
    {
        if (File.Exists(filePathFilename))
        {
            return true;
        }
        else
        {
           MessageBox.Show("Can not open Existing File.");
           return false;
        }
    }

Upvotes: 0

Kyle Cronin
Kyle Cronin

Reputation: 79093

That doesn't even appear to be a recursive function. I don't see how that would cause a stack overflow.

In order to overflow a stack you have to continually call functions from within functions. Every time you do this, more stack space is used to resume the calling function when the called function returns. Recursive functions run into this problem because they need to store multiple copies of the state of the same function, one for each level of recursion. This can also happen in mutually recursive functions (A calls B, B calls A) and it can be harder to detect, but I don't think that's the case here.

Upvotes: 9

Chris Ballance
Chris Ballance

Reputation: 34337

Only problem I could think of is if you have something crazy going on in this function which you do not list code for filePathFilenameExists()

Upvotes: 0

Paul Fisher
Paul Fisher

Reputation: 9666

Calling this function will not cause a "stack overflow". You can only cause a stack overflow by a function calling itself recursively. I'll explain briefly:

When you call a function in a program, it creates a new entry on the "call stack". This contains a little information about the current function, the place it was called from, and the local variables of the function. This entry, as I said, is created when you call the function, but when you return from the function, throw an exception, or simply let the function reach its end, the system uses that information to return to the previous point of execution, then removes that entry from the call stack.

So, before you call your function, you might have on the stack:

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

then, you call the LogString function:

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

But after LogString completes, the code will return to performComplexOperation using the return address. The entry for LogString will be removed:

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

In a stack overflow, the space taken by the entries on the stack will exceed the space alloted for the stack by the language you're using*, and the program won't be able to create the entry for the function you're about to call.

* Not exactly, but close enough.

Upvotes: 0

Zach Scrivena
Zach Scrivena

Reputation: 29539

In response to OP's update: The problem is probably with the caller method, and not LogString() itself. If the caller method is indeed a recursive method, then there is certainly a risk of stackoverflowing if the allocated stack size is not big enough.

Upvotes: 0

JSmyth
JSmyth

Reputation: 12153

Are you asking if it will it cause a stackoverflow or why does it cause a stackoverflow?

Stackoverflows (usually) happen when recursion goes slightly wrong.

Upvotes: 0

Related Questions