-1

So - I still can't figure out why this line:

List<string> strTemp = new List<string>();

Would throw this error:

Index was outside the bounds of the array.

Some context: Recursive function, called (initially) from function launched in separate thread from Web Service (IIS).

Also - lest too many jump in with "perhaps you are looking at the wrong line..." - no. easily confirmed. Move line, moves error, with each deployment.

Oh - and for the record - not always, it's an occasional (they're so much fun). From what I can see in the event log, no issues "around" the time of the flagging that would indicate any complicating factor.

Edit: some details for the comments below. public class for service: SuperCloud
public class for queuer: PHQ
public function (called from service): void OnStop()
public function causing error: (snip from decl to line in question)

    public string CoalesceStrings(List<string> strIn, string[] strDelim = null)
    {
        string strReturn;
        List<string> strTempReturn;
        List<string> strTemp = new List<string>(); //<== error here!
        string[][] strTemp2;
        int iCount, iCap = int.MaxValue;

        if (strDelim == null)
            strDelim = new string[] { "." };

        iCount = strIn.Count;
        strTemp2 = new string[iCount][];

        for (int i = 0; i < iCount; i++)
        {
            strTemp2[i] = strIn[i].Split(strDelim, StringSplitOptions.None);
            if (strTemp2[i].Length < iCap)
                iCap = strTemp2[i].Length;
        }

        strTempReturn = new List<string>();
        if (strDelim[0] == ".")
            --iCap;

        for (int i = 0; i < iCap; i++)
        {
            bool bMatch = true;
            strTemp.Clear();
            strTemp.Add( strTemp2[0][i] );

            for (int j = 1; j < iCount; j++)
            {
                strTemp.Add(strTemp2[j][i]);
                if (bMatch && (strTemp2[j][i] != strTemp2[0][i]))
                    bMatch = false;
            }

            if (bMatch)
                strTempReturn.Add(strTemp2[0][i]);
            else if (strDelim[0] == "." )
                strTempReturn.Add( CoalesceStrings( strTemp, new string [] {"_"} ));
        }

        if (strDelim[0] == ".")
            strTempReturn.Add(strTemp2[0][strTemp2[0].Length - 1]);

        if (strTempReturn.Count == 0)
            strReturn = "";
        else
        {
            strReturn = strTempReturn[0];

            for (int i = 1; i < strTempReturn.Count; i++)
                strReturn = string.Concat(strReturn, strDelim[0], strTempReturn[i]);
        }

        return strReturn;
    }

edited: added full function for mjwillis call: CoalesceStrings(strFileName);

basically: the function will take a set of files that originated from a single file, that were split, according to an unknown algorithm, and "unsplit" it, to get the original file name. The logic itself works (the times it doesn't throw the error).

example: input: { "foo.bar.1.1.prelim", "foo.bar.1.1.final", "foo.bar.1.2.prelim",...,"foo.bar.4.5.final" } output: "foo.bar"

John
  • 182
  • 7
  • Please share the stacktrace for folks to see what could cause this. – shahkalpesh Jun 01 '17 at 14:40
  • 2
    Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error **and the shortest code necessary to reproduce it** in the question itself. Line `List strTemp = new List();` is not reproducing your issue – Sergey Berezovskiy Jun 01 '17 at 14:42
  • @shahkalpesh - stack trace is a bit tough, as I'm forced to pull what I can (no access to run a debugger on the IIS server) - from my logs: at SuperCloud.PHQ.CoalesceStrings(List`1 strIn, String[] strDelim) in C:\SuperCloud\SuperCloudSvc\Queuer.cs:line 263 at SuperCloud.PHQ.OnStop() in C:\SuperCloud\SuperCloudSvc\Queuer.cs:line 431 --- indication that is the inital call, and not the recursion. I'll update the post for details – John Jun 01 '17 at 14:42
  • @SergeyBerezovskiy: again, not quite so simple... any shortest route, won't create it - heck, most of the time, the EXISTING code doesn't create it. (note: the "occasional") - happens about once every 20 times or so.... – John Jun 01 '17 at 14:45
  • you must be stuck in an endless loop and eventually running out of memory. So you end up with a list that doesn't get constructed and have zero items. – jdweng Jun 01 '17 at 14:51
  • @jdweng - without the recursion, not sure if it's possible. Thanks for making me double check, however, I saw one oddity that might be of interest, but I'll need to confirm. There is a possibility (only a possibility - I'll need to confirm, the next time it rears its ugly head) that the call that is flagging is coming in with strIn = null (though, I don't see how that would make a difference) – John Jun 01 '17 at 15:06
  • Can you show us the 2 lines of code prior to this line, and also the 2 lines of code after it? I am 60% sure the line that is throwing the exception is the line prior to the one you are showing here. – mjwills Jun 03 '17 at 12:51
  • @mjwills - I will add to the original, note: it behaves better with everything public, but not 100% yet (NOTE: the couple before were already shown) – John Jun 08 '17 at 13:03
  • Can you show us the entirety of the CoalesceStrings method? – mjwills Jun 08 '17 at 13:06
  • @mjwills: done. – John Jun 08 '17 at 13:15
  • 1
    The bug is that the code is too complicated for its own good. If, as it appears, `CoalesceStrings` should be called `FindLongestCommonPrefix`, that suggests [simpler solutions](https://stackoverflow.com/questions/2070356/find-common-prefix-of-strings). Possibly a bit more involved than that, but certainly not as involved as what's on display here. The recursion and nested arrays aren't helping. – Jeroen Mostert Jun 08 '17 at 13:33
  • @JeroenMostert: it very well could be. I chalk that up to the nature of the dev process. I'll have to confirm that the solution would work (I assume it would, even though the intermediaries are used/stored) – John Jun 08 '17 at 13:52
  • @JeroenMostert: Also - whether it works or not, the question remains unanswered. What would cause THAT line to throw THAT error? Part of the problem (and I suspect why the question keeps getting voted down) is that I am NOT looking for working code (that's simple enough). I'm looking to know how that error could come from a declaration line. – John Jun 08 '17 at 14:08
  • That one, at least, is usually easy -- line numbers in stack traces of optimized code are unfortunately hideously unreliable, because optimization can move code around and simplify other code. And that's *assuming* you've always got the most up to date `.pdb` along with the code. I can guarantee that the constructor of `List` isn't the code throwing the exception. If you have a debug build and a good `.pdb` and it's still showing the wrong line numbers, things are slightly more interesting. You can always get the *exact* location from a crash dump, but that's quite involved. – Jeroen Mostert Jun 08 '17 at 14:15
  • @JeroenMostert: pulled this from another post - same class, different method: and now the phantom error has moved to the first initialization in the function. at first - bool bReturn = false; was returning the " Object reference not set to an instance of an object." error, and when I split that up, moving the assignment below the declaration block, the following line - int i = 0; starting raising it... sigh this is a rough one – John May 30 at 20:07 --- This was resolved by declaring the method "private". Not sure if it shed any light – John Jun 08 '17 at 14:18
  • Are you running debug or release builds? And, a @JeroenMostert has raised already - is there an up to date pdb there a well? – mjwills Jun 09 '17 at 13:01
  • the answer is "yes" - it's a production release of a debug build. It's a hardware dependent system, so there is no need to lock down the code (as of yet). Until I work out a mess of other issues, having the debug info helps. The pdb is updated with every release. – John Jun 12 '17 at 14:27

1 Answers1

0

Change:

    if (strDelim == null)
        strDelim = new string[] { "." };

to:

    if (strDelim == null || !strDelim.Any())
        strDelim = new string[] { "." };

    if (strIn == null)
        strIn = new List<string>();

Does that help?

Honestly, it would help greatly if the variable names weren't all derivations of temp - it makes it very hard to work out what the code is even trying to do...

mjwills
  • 23,389
  • 6
  • 40
  • 63
  • will do - it may take some time to know for sure, however - as mentioned, it's an "occassional" exception – John Jun 08 '17 at 13:26
  • @mjwillis: if we are truly going for a "different location"... I just noticed this line (easier to see outside of IDE): strTemp2[i] = strIn[i].Split(strDelim, StringSplitOptions.None); (that's a red flag) – John Jun 08 '17 at 13:30
  • Agreed, that is another possible culprit. – mjwills Jun 08 '17 at 13:35
  • just checked - my bad, it wants an array there, not a string (language confusion on my part. That's the split method of string, not the split function (taking the string as the first param). – John Jun 08 '17 at 13:36