0

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

    }
3
  • 1
    It may not result in a stack overflow, but it resulted in stackoverflow. Commented Feb 10, 2009 at 4:41
  • There is no reason to call Flush and Close on the stream as this is already handled by the using construct. Commented Feb 10, 2009 at 19:11
  • Just for the record, I guess you don't want to display 600 messageboxes a second so I guess you should either make sure to display it only once or use some other means of error reporting. Commented Feb 10, 2009 at 19:11

13 Answers 13

9

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Obviously filePathFilenameExists is implemented recursively :D
3

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.

1 Comment

I use two threads, but one thread is disposed after 5 seconds when the program is executed thus only the main thread will continue to run the rest of the program. If it's shared violation, it should display message right? because I got this type of error before.
2

@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.

Comments

1

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?

4 Comments

I create one global array that has size of 400, and three more ArrayList, but it's very small, maybe 30 max. The call stack, I look at it and it does has repetitive traces because number of calls from FunctionA to FunctionB is based on the size of array[400] which is the purpose of the program.
It has to take each item in the array[400] and validate it then take next item out from array[400] until there is no more then will stop the calls.
I reduce the arrays from 400 to 224, there is still error. When I reduce 224 to 43, it executes nicely without exception.
If you post the call stack and some of the code that is controlled by the array, we might be able to help you with pinpointing the actual problem. Do you happen to be passing that array as a parameter to the recursing functions? You can try boxing the array in an object and passing reference to it.
0

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.

Comments

0

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.

Comments

0

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.

5 Comments

Your stack is upside down! =D
;) backwards think can't I but ,perhaps
based on everyone's respond this function will not cause stackoverflow, but the exception always points to that function called; or is it the error caused earlier?
The error is CAUSED on LogString because it's exactly then where it runs out of stack space. But it's likely the function that calls LogString that is the culprit.
I look at the call stack on IDE and I don't see anything weird for example. FunctionA calls FunctionB, FunctionA calls functionC, FunctionA calls FunctionD, and so on. FunctionA shows up alot because it reads each content from the array then pass to FunctionB,C,D. FunctionA will stop call when it
0

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()

Comments

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

1 Comment

You should not be displaying a message box in that method. Just return false.
0

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?

9 Comments

how can I find out the stack size when stackoverflow is thrown? Since I programmed, I've never thought about stack size because my program is not huge, but can u tell me how can I find out the stack based on your first question.
filepathFileName is a public member data that is assigned inside the class library constructor. Not sure what u meant the 'your getter' logString will be called many times, but not an infinit loop calls.
Are you using Visual Studio? If so, when the exception is thrown, you can look at the call stack window. If you see many calls to a certain function (particularly in a row), that's probably the culprit.
if filePathFileName is a public member, then it doesn't matter. By 'getter', I meant if it were a property that you can specify a get function. If perhaps filePathFileName's get function was calling LogString, which was in turn calling filePathFileName's get function again...
thanks for responding. In my program I declare global variable of array type then later in the function body(not constructor) I allocate array with size 224. Each array index corresponds to each case scenario. Each scenario is a function so each function will get called.
|
0

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.

1 Comment

actuallly this is my first post as well.
0

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.