简体   繁体   中英

Index was outside the bounds of the array? I'm not sure. C#

I'd like to create a method, that searches the highest values in an array and creates another array with them. Then, all those values should be printed in richTextBox (because afterwards I'll bound them with text, which I'd like to print with each one).

The code of my method:

private void selectPattern() {
    int[] tab = new int[12];
    int max = 0;
    int k = 0;
    int[] j = new int[12];

    for (int l = 0; l < 12; l++) {
        j[l] = 0;
    }

    // Patterns

    tab[0] = 3;
    tab[1] = 2;
    tab[2] = 5;
    tab[3] = 7;
    tab[4] = 1;
    tab[5] = 4;
    tab[6] = 4;
    tab[7] = 11;
    tab[8] = 3;
    tab[9] = 11;
    tab[10] = 11;
    tab[11] = 3;

    // Counting
    for (int i = 0; i < 12; i++) {
        if (tab[i] >= max) {
            max = tab[i];
            j[k] = i;
            k++;
            for (k = 0; k < 12; k++) {
                if (j[k] != 0) {
                    richTextBox1.Text = j[k].ToString();
                    richTextBox1.Text = Environment.NewLine;
                }
            }
        }
    }
}

But it worked only for the first time and now I'm getting:

System.IndexOutOfRangeException: Index was outside the bounds of the array. at WindowsFormsApp2.Form1.selectPattern() in Form1.cs:line 59

Line 59 is this:

j[k] = i;

I'm setting the 0 value for k at the beginning of the method, so I assumed, that index should be rewritten every time I call this method. Could anyone explain me, why is it not working?

Thanks for any help

@EDIT The code with more descriptive names of variables

private void selectPattern()
    {
        int[] valueTab = new int[12];
        int maxValue = 0;
        int indexIndex = 0;
        int[] indexTab = new int[12];

        //Filling indexTab with zeroes

        for (int zeroIndex = 0; zeroIndex < 12; zeroIndex++)
        {
            indexTab[zeroIndex] = 0;
        }

        //Patterns

        valueTab[0] = 3;
        valueTab[1] = 2;
        valueTab[2] = 5;
        valueTab[3] = 7;
        valueTab[4] = 1;
        valueTab[5] = 4;
        valueTab[6] = 4;
        valueTab[7] = 11;
        valueTab[8] = 3;
        valueTab[9] = 11;
        valueTab[10] = 11;
        valueTab[11] = 3;

        //Counting
            for (int valueIndex = 0; valueIndex < 12; valueIndex++)
            {
                if (valueTab[valueIndex] >= maxValue)
                {
                    maxValue = valueTab[valueIndex];
                    indexTab[indexIndex] = valueIndex;
                    indexIndex++;
                    for (indexIndex = 0; indexIndex < 12; indexIndex++)
                    {
                        if (indexTab[indexIndex] != 0)
                        {
                            richTextBox1.Text = indexTab[indexIndex].ToString();
                            richTextBox1.Text = Environment.NewLine;
                        }
                        else
                        {
                            richTextBox1.Text = "." + Environment.NewLine;
                        }
                    }
                    indexIndex = 0;
                }

            }

        }

After the for ( k = 0; ... loop finishesfor the first time, value of k is 12. So you are then trying to assign to j[k] which is j[12] which is out of bounds.

The value of k is set to 0 each time you call the method itself, but it isn't set to 0 after during at the beginning of the for ( int i = 0; ... loop body, so the value of 12 persists from the first execution ( i = 0 ) to the second one ( i = 1 ).

You should give your variables a descriptive name. It will help you and others understand the code much better and avoid many problems. After deliberate effort I think you wanted something like the following instead:

// find max values
for (int i = 0; i < 12; i++) {
    if ( tab[i] > max ) k = 0; //reset position in target array for new max
    if ( tab[i] >= max ) {
        max = tab[i];
        j[k] = i;            
        k++;
    }
}
// print max values
for (k = 0; k < 12; k++) {
   if (j[k] != 0) {
       richTextBox1.Text = j[k].ToString();
       richTextBox1.Text = Environment.NewLine;
   }
}   

Now see the same with more descriptive variable names and less hard-coded magical constants:

private void PrintOutMaxValues() 
{
    int currentMax = 0;

    var input = new int[] { 3, 2, 5, 7, 1, 4, 4, 11, 3, 11, 11, 3 };
    var maxCounter = 0;

    // find max values
    for ( int inputIndex = 0; inputIndex < input.Length; inputIndex++) 
    {
        if ( input[ inputIndex ] > currentMax )
        {
           currentMax = input[ inputIndex ];
           maxCounter = 1;
        }
        else if ( input[ inputIndex ] == currentMax ) 
        {
           maxCounter++;
        }
    }

    //print out the maximum the number of times it occurred
    for ( var resultIndex = 0; resultIndex < maxCounter; resultIndex++) 
    {
        richTextBox1.Text += currentMax.ToString();
    }
}

The code does "almost" the same thing (because I am still not sure about the desired ouptut), but as you can see, giving the variables longer and more descriptive names makes it easier to understand the result and the intentions of the developer :-) . In case of coding, more is sometimes actually more, not less ;-) . Writing one character variable names saves you time while writing, but it will cost you much more when trying to find and fix bugs that were unintentionally created.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM