Index was outside the bounds of the array ошибка

I'm aware of what the issue is stating but I am confused to how my program is outputting a value that's outside of the array.. I have an array of ints which is 0 - 8 which means it can hold 9 ints,

I’m aware of what the issue is stating but I am confused to how my program is outputting a value that’s outside of the array..

I have an array of ints which is 0 — 8 which means it can hold 9 ints, correct?
I have an int which is checked to make sure the users input value is 1-9. I remove one from the integer (like so)

if (posStatus[intUsersInput-1] == 0) //if pos is empty
{
    posStatus[intUsersInput-1] += 1; 
}//set it to 1

then I input 9 myself and I get the error. It should access the last int in the array, so I don’t see why I’m getting an error.
Relevant code:

public int[] posStatus;       

public UsersInput()    
{    
    this.posStatus = new int[8];    
}

int intUsersInput = 0; //this gets try parsed + validated that it's 1-9    

if (posStatus[intUsersInput-1] == 0) //if i input 9 it should go to 8?    
{    
    posStatus[intUsersInput-1] += 1; //set it to 1    
} 

Error:

"Index was outside the bounds of the array." "Index was outside the bounds of the array."

pravprab's user avatar

pravprab

2,3013 gold badges27 silver badges42 bronze badges

asked Feb 11, 2014 at 11:43

Zain's user avatar

2

You have declared an array that can store 8 elements not 9.

this.posStatus = new int[8]; 

It means postStatus will contain 8 elements from index 0 to 7.

answered Feb 11, 2014 at 11:46

M.S.'s user avatar

M.S.M.S.

4,2531 gold badge18 silver badges40 bronze badges

0

public int[] posStatus;       

public UsersInput()    
{    
    //It means postStatus will contain 9 elements from index 0 to 8. 
    this.posStatus = new int[9];   
}

int intUsersInput = 0;   

if (posStatus[intUsersInput-1] == 0) //if i input 9, it should go to 8?    
{    
    posStatus[intUsersInput-1] += 1; //set it to 1    
} 

Anthony Horne's user avatar

answered Feb 11, 2014 at 11:47

Suman Banerjee's user avatar

Suman BanerjeeSuman Banerjee

1,8754 gold badges24 silver badges39 bronze badges

//if i input 9 it should go to 8?

You still have to work with the elements of the array. You will count 8 elements when looping through the array, but they are still going to be array(0) — array(7).

answered Feb 11, 2014 at 11:45

Jason Sgalla's user avatar

1

  • Question

  • Hello,

    I have a code which enters data from textboxes into database.it is as followed:

    private void ExecuteInsert(string GrNo, string Name, string DOB, string Std, string Div, string RollNo, string Sex, string MobileNo, string Address, string TelNo, string FathersName, string FathersProfession, string MothersName, string MothersProfession, string Age, string Year)
            {
                SqlConnection conn = new SqlConnection("Data Source =.;Initial Catalog=SAHS;User id=sa;password=faculty");
                string sql = "INSERT INTO dbo.Student_Details (GrNo,Name,DOB,Std,Div,RollNo,Sex,MobileNo,Address,TelNo,FathersName,FathersProfession,MothersName,MothersProfession,Age,Year) VALUES "
                            + " (@GrNo,@Name,@DOB,@Std,@Div,@RollNo,@Sex,@MobileNo,@Address,@TelNo,@FathersName,@FathersProfession,@MothersName,@MothersProfession,@Age,@Year)";
    
                try
                {
                    conn.Open();
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    SqlParameter[] param = new SqlParameter[5];
                    param[0] = new SqlParameter("@GrNo", SqlDbType.Int);
                    param[1] = new SqlParameter("@Name", SqlDbType.NVarChar, 50);
                    param[2] = new SqlParameter("@DOB", SqlDbType.DateTime);
                    param[3] = new SqlParameter("@Std", SqlDbType.Int);
                    param[4] = new SqlParameter("@Div", SqlDbType.NVarChar, 5);
                    param[5] = new SqlParameter("@RollNo", SqlDbType.Int);
                    param[6] = new SqlParameter("@Sex", SqlDbType.Char, 1);
                    param[7] = new SqlParameter("@MobileNo", SqlDbType.NVarChar, 14);
                    param[8] = new SqlParameter("@Address", SqlDbType.NVarChar, 200);
                    param[9] = new SqlParameter("@TelNo", SqlDbType.Int);
                    param[10] = new SqlParameter("@FathersName", SqlDbType.NVarChar, 50);
                    param[11] = new SqlParameter("@FathersProfession", SqlDbType.NVarChar, 25);
                    param[12] = new SqlParameter("@MothersName", SqlDbType.NVarChar, 50);
                    param[13] = new SqlParameter("@MothersProfession", SqlDbType.NVarChar, 25);
                    param[14] = new SqlParameter("@Age", SqlDbType.Int);
                    param[15] = new SqlParameter("@Year", SqlDbType.NVarChar, 10);
    
                    param[0].Value = GrNo;
                    param[1].Value = Name;
                    param[2].Value = DOB;
                    param[3].Value = Std;
                    param[4].Value = Div;
                    param[5].Value = RollNo;
                    param[6].Value = Sex;
                    param[7].Value = MobileNo;
                    param[8].Value = Address;
                    param[9].Value = TelNo;
                    param[10].Value = FathersName;
                    param[11].Value = FathersProfession;
                    param[12].Value = MothersName;
                    param[13].Value = MothersProfession;
                    param[14].Value = Age;
                    param[15].Value = Year;
    
                    for (int i = 0; i < param.Length; i++)
                    {
                        cmd.Parameters.Add(param[i]);
                    }
    
                    cmd.CommandType = CommandType.Text;
                    cmd.ExecuteNonQuery();
                }
                catch (System.Data.SqlClient.SqlException ex)
                {
                    string msg = "Insert Error:";
                    msg += ex.Message;
                    throw new Exception(msg);
                }
                finally
                {
                    conn.Close();
                }
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
             ExecuteInsert(textBox1.Text, textBox2.Text, dateTimePicker1.Text,textBox4.Text,/*textBox4.Text*/ textBox5.Text, textBox6.Text, textBox7.Text, textBox8.Text, textBox9.Text, textBox10.Text, textBox11.Text, textBox12.Text, textBox13.Text, textBox14.Text, textBox15.Text,textBox16.Text);
                            MessageBox.Show("Record was successfully added!");
                            ClearTextBoxes(this);
                            label18.Visible = false;
                            label19.Text = "";
                            label20.Text = "";
                            break;
    
    }
    
    
    
    
    
    param[5] = new SqlParameter("@RollNo", SqlDbType.Int);

    Here when i enter a value , it gives an error message «Index was outside the bounds of the array c#»

    please help what should i do..

Answers

  • Hi, since you add 16 parameters, you should resize your array to:

      SqlParameter[] param = new SqlParameter[15];


    Mitja

    • Proposed as answer by

      Monday, August 27, 2012 7:14 PM

    • Marked as answer by
      Harshal Mehta
      Thursday, August 30, 2012 4:12 PM

  • It should be 16 since your array starts with 0.

    SqlParameter[] param =
    new SqlParameter[16];


    jdweng

    • Proposed as answer by
      Rajeev Harbola
      Tuesday, August 28, 2012 11:19 AM
    • Marked as answer by
      Jason Dot WangModerator
      Tuesday, September 4, 2012 8:40 AM

  • It should be 16 since your array starts with 0.

    SqlParameter[] param =
    new SqlParameter[16]


    Wrong. For that reason should be 15. As you say he have 16 params, starting with 0. When he reach param[15], he will reach all the 16 parameters.


    Web Developer

    • Proposed as answer by
      Akayster
      Monday, August 27, 2012 7:52 PM
    • Marked as answer by
      Jason Dot WangModerator
      Tuesday, September 4, 2012 8:40 AM

  • Oh for Heaven’s sake!

    Mitja made an obvious typo. Harshal’s code calls for 16 elements, numbered 0 to 15. Therefore he needs to declare his array as having 16 elements, just as Joel said.

    If the array is declared like this…

    SqlParameter[] param =
    new SqlParameter[15];

    …then when he tries to do this…

                    param[15] = new SqlParameter("@Year", SqlDbType.NVarChar, 10);

    …there will be a crash.

    • Edited by
      Ante Meridian
      Tuesday, August 28, 2012 12:23 AM
    • Proposed as answer by
      DanyR_
      Tuesday, August 28, 2012 5:19 PM
    • Marked as answer by
      Jason Dot WangModerator
      Tuesday, September 4, 2012 8:40 AM

  • Hey Harshal Mehta:)

    Another easy way is using AddWithValue!

    private void ExecuteInsert(string
    GrNo, string
    Name, string DOB,
    string Std,
    string Div, string
    RollNo, string
    Sex, string MobileNo,
    string Address,
    string TelNo, string
    FathersName, string
    FathersProfession, string
    MothersName, string
    MothersProfession, string
    Age, string
    Year)
           
    {
               
    SqlConnection conn
    = new SqlConnection(«Data Source =.;Initial Catalog=SAHS;User id=sa;password=faculty»);
               
    string sql
    = «INSERT INTO dbo.Student_Details (GrNo,Name,DOB,Std,Div,RollNo,Sex,MobileNo,Address,TelNo,FathersName,FathersProfession,MothersName,MothersProfession,Age,Year) VALUES «
                           
    + » (@GrNo,@Name,@DOB,@Std,@Div,@RollNo,@Sex,@MobileNo,@Address,@……)
                SqlCommand cmd = new SqlCommand(sql,conn);
                cmd.Parameters.AddWithValue(«@YourParameter’s name»,»Your Real Value»);
                  ……………………………………
             }


    下载MSDN桌面工具(Vista,Win7)

    我的博客园
    慈善点击,点击此处

    • Proposed as answer by
      Jason Dot WangModerator
      Wednesday, August 29, 2012 7:51 AM
    • Marked as answer by
      Jason Dot WangModerator
      Tuesday, September 4, 2012 8:40 AM

Improve Article

Save Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    C# supports the creation and manipulation of arrays, as a data structure. The index of an array is an integer value that has value in the interval [0, n-1], where n is the size of the array. If a request for a negative or an index greater than or equal to the size of the array is made, then the C# throws an System.IndexOutOfRange Exception. This is unlike C/C++ where no index of the bound check is done. The IndexOutOfRangeException is a Runtime Exception thrown only at runtime. The C# Compiler does not check for this error during the compilation of a program.

    Example:

    using System;

    public class GFG {

        public static void Main(String[] args)

        {

            int[] ar = {1, 2, 3, 4, 5};

            for (int i = 0; i <= ar.Length; i++)

                Console.WriteLine(ar[i]);

        }

    }

    Runtime Error:

    Unhandled Exception:
    System.IndexOutOfRangeException: Index was outside the bounds of the array.
    at GFG.Main (System.String[] args) <0x40bdbd50 + 0x00067> in :0
    [ERROR] FATAL UNHANDLED EXCEPTION: System.IndexOutOfRangeException: Index was outside the bounds of the array.
    at GFG.Main (System.String[] args) <0x40bdbd50 + 0x00067> in :0

    Output:

    1
    2
    3
    4
    5
    

    Here if you carefully see, the array is of size 5. Therefore while accessing its element using for loop, the maximum value of index can be 4 but in our program, it is going till 5 and thus the exception.

    Let’s see another example using ArrayList:

    using System;

    using System.Collections;

    public class GFG {

        public static void Main(String[] args)

        {

            ArrayList lis = new ArrayList();

            lis.Add("Geeks");

            lis.Add("GFG");

            Console.WriteLine(lis[2]);

        }

    }

    Runtime Error: Here error is a bit more informative than the previous one as follows:

    Unhandled Exception:
    System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index
    at System.Collections.ArrayList.get_Item (Int32 index) <0x7f2d36b2ff40 + 0x00082> in :0
    at GFG.Main (System.String[] args) <0x41b9fd50 + 0x0008b> in :0
    [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index
    at System.Collections.ArrayList.get_Item (Int32 index) <0x7f2d36b2ff40 + 0x00082> in :0
    at GFG.Main (System.String[] args) <0x41b9fd50 + 0x0008b> in :0

    Lets understand it in a bit of detail:

    • Index here defines the index we are trying to access.
    • The size gives us information of the size of the list.
    • Since size is 2, the last index we can access is (2-1)=1, and thus the exception

    The correct way to access array is :

    for (int i = 0; i < ar.Length; i++) 
    {
    }
    

    Handling the Exception:

    • Use for-each loop: This automatically handles indices while accessing the elements of an array.
      • Syntax:
        for(int variable_name in array_variable)
        {
             // loop body
        }
        
        
    • Use Try-Catch: Consider enclosing your code inside a try-catch statement and manipulate the exception accordingly. As mentioned, C# won’t let you access an invalid index and will definitely throw an IndexOutOfRangeException. However, we should be careful inside the block of the catch statement, because if we don’t handle the exception appropriately, we may conceal it and thus, create a bug in your application.

    Очень часто при работе с массивами или коллекциями можно столкнуться с исключением: Index was out of range. В чём заключается суть ошибки.

    Представьте, что у Вас есть массив, состоящий из двух элементов, например:

    int [] ar = new int [] {5,7};

    Особенность массивов в языке c# заключается в том, что начальный индекс элемента всегда равен нулю. То есть в данном примере, не смотря на то, что число пять — это первое значение элемента массива, при обращении к нему потребуется указать индекс ноль. Так же и для числа семь, несмотря на то, что это число является вторым элементом массива, его индекс так же будет на единицу меньше, то есть, равен одному.

    Обращение к элементам массива:

    int a = ar[0];
    int b = ar[1];

    Результат: a = 5 и b = 7.

    Но, стоит только указать неверный индекс, например:

    int a = ar[2];

    В результате получаем исключение: Index was outside the bounds of the array, то есть индекс находиться за границами диапазона, который в данном примере составляет от 0 до 1. Поэтому при возникновении данной ошибки, первое, что нужно сделать, так это убедиться в том, что Вы указали правильный индекс при обращении к элементу массива или обобщённой коллекции.

    Exception

    Так же данная ошибка очень часто встречается в циклах, особенно в цикле for, если Вы указываете неверное количество элементов содержащихся в массиве, например:

    List<int> ar = new List<int> {8,9};
    for (int i = 0; i < 3; i++)
    {
    int a = ar[i];
    };

    В результате так же возникает ArgumentOutOfRangeException, так как количество элементов равно двум, а не трём. Поэтому лучше всего в циклах использовать уже готовые методы для подсчёта количества элементов массива или коллекций, например:

    для массива

    for (int i = 0; i < ar.Length; i++)
    {
    int a = ar[i];
    };

    для коллекции

    List<int&gt; ar = new List<int> {5,7};
    for (int i = 0; i < ar.Count; i++)
    {
    int a = ar[i];
    }

    Говоря про циклы нельзя не упомянуть ещё одну ошибку, которая очень часто встречается у многих начинающих программистов. Представим, что у нас есть две коллекции и нам нужно заполнить список var2 значениями из первого списка.

    List<string> var = new List<string> {"c#", "visual basic", "c++"};
    List<string> var2 = new List<string> {};
    for (int i = 0; i < var.Count; i++)
    {
    var2[i] = var[i].ToString();
    }

    Не смотря на то, что вроде бы все указано, верно, в результате выполнения кода, уже на самом первом шаге цикла, будет выдано исключение: Index was out of range. Это связано с тем, что для заполнения коллекции var2 требуется использовать не индекс, а метод Add.

    for (int i = 0; i < var.Count; i++)
    {
    var2.Add(var[i].ToString());
    }

    Если же Вы хотите отловить данное исключение, в ходе выполнения программы, то для этого достаточно воспользоваться блоками try catch, например:

    try
    {
    for (int i = 0; i < var.Count; i++)
    {
    var2[i] = var[i].ToString();
    }
    }
    catch (ArgumentOutOfRangeException e)
    {
    Console.WriteLine(e.Message);
    }
    }

    Читайте также:

    • Как очистить listbox?
    • Динамическое добавление узлов в элементе TreeView
    • Поиск html элемента с атрибутом id


    DAndrew

    0 / 0 / 0

    Регистрация: 20.12.2020

    Сообщений: 4

    1

    20.12.2020, 14:47. Показов 6366. Ответов 7

    Метки нет (Все метки)


    Пытаюсь написать простую программу по выводу массива на экран. Visual Studio показывает 0 ошибок, но пи попытке компиляции выдаёт Index was outside the bounds of the array. Что делать, как исправить? Код программы:

    C#
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    class Program
        {
            static void Main(string[] args)
            {
                int i;
                int[] MyArray = new int[5] { 1, 2, 3, 4, 5 };
                Console.WriteLine(MyArray[5]);
                for (i = 0; i < 5; i++)
                {
                    MyArray[i] = int.Parse(Console.ReadLine());
                }
            }
        }

    __________________
    Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



    0



    958 / 576 / 268

    Регистрация: 20.12.2016

    Сообщений: 1,506

    20.12.2020, 14:49

    2

    Цитата
    Сообщение от DAndrew
    Посмотреть сообщение

    Console.WriteLine(MyArray[5]);

    индексы массива от 0 до 4



    0



    0 / 0 / 0

    Регистрация: 20.12.2020

    Сообщений: 4

    20.12.2020, 14:57

     [ТС]

    3

    То есть записать так
    Console.WriteLine(MyArray[5] { 0, 1, 2, 3, 4 }); ?

    Добавлено через 3 минуты
    Тут int[] MyArray = new int[5] { 1, 2, 3, 4, 5 }; поправил на int[] MyArray = new int[5] { 0, 1, 2, 3, 4 };
    но не помогло



    0



    ProgItEasy

    454 / 278 / 163

    Регистрация: 17.04.2019

    Сообщений: 1,603

    20.12.2020, 14:59

    4

    DAndrew,

    C#
    1
    
    Console.WriteLine(MyArray[4]);



    0



    JustinTime

    958 / 576 / 268

    Регистрация: 20.12.2016

    Сообщений: 1,506

    20.12.2020, 15:01

    5

    у вас массив int[] MyArray = new int[5] { 1, 2, 3, 4, 5 };, вы можете обращаться к его элементам указывая индекс от 0 до 4

    C#
    1
    2
    3
    4
    5
    6
    7
    
    Console.WriteLine(MyArray[0]);
    Console.WriteLine(MyArray[1]);
    Console.WriteLine(MyArray[2]);
    Console.WriteLine(MyArray[3]);
    Console.WriteLine(MyArray[4]);
    //а строка ниже с ошибкой, в массиве нет такого элемента, вы выходите за пределы массива
    Console.WriteLine(MyArray[5]);



    0



    0 / 0 / 0

    Регистрация: 20.12.2020

    Сообщений: 4

    20.12.2020, 15:07

     [ТС]

    6

    Console.WriteLine(MyArray[0]);
    Console.WriteLine(MyArray[1]);
    Console.WriteLine(MyArray[2]);
    Console.WriteLine(MyArray[3]);
    Console.WriteLine(MyArray[4]);
    А можно ли это записать одной строкой?



    0



    JustinTime

    958 / 576 / 268

    Регистрация: 20.12.2016

    Сообщений: 1,506

    20.12.2020, 15:11

    7

    Лучший ответ Сообщение было отмечено DAndrew как решение

    Решение

    можно:

    C#
    1
    
    Console.WriteLine(MyArray[0]);Console.WriteLine(MyArray[1]);Console.WriteLine(MyArray[2]);Console.WriteLine(MyArray[3]);Console.WriteLine(MyArray[4]);

    :-) у вас есть цикл для ввода значений так же можно и выводить, или используйте

    C#
    1
    
    Console.WriteLine(string.Join(" ", MyArray));



    1



    0 / 0 / 0

    Регистрация: 20.12.2020

    Сообщений: 4

    20.12.2020, 15:13

     [ТС]

    8

    Спасибо, всё работает



    0



    IT_Exp

    Эксперт

    87844 / 49110 / 22898

    Регистрация: 17.06.2006

    Сообщений: 92,604

    20.12.2020, 15:13

    Помогаю со студенческими работами здесь

    Ошибка System.IndexOutOfRangeException: «Index was outside the bounds of the array»
    В двумерном массиве A=(a1, а2, …, аn) отрицательные элементы, имеющие четный порядковый номер,…

    Ошибка «Index was outside the bounds of the array» при отправке сообщения с вложениями
    При отправке сообщения с вложениями выскакивает вот эта ошибка:

    Что это может быть?

    Index was outside the bounds of the array
    Скажите пожалуйста, почему у меня выдает ошибку, которая в заголовке. Причем эта ошибка указывает…

    Index was outside the bounds of the array
    Помогите пожалуйста. На другом компе все работало, на этом не хочет. В ответе выходило -48.
    сейчас…

    Index was outside the bounds of the array
    Всем привет, есть задание, надо создать программу которая используя частотный анализ будет…

    Index was outside the bounds of the array
    Здравствуйте. Изучаю пример на VB2010. Считываю COMport. При первом считывании работает, а при…

    Искать еще темы с ответами

    Или воспользуйтесь поиском по форуму:

    8

    Почему возникает исключение: Index was out of range?

    Очень часто при работе с массивами или коллекциями можно столкнуться с исключением: Index was out of range. В чём заключается суть ошибки.

    Представьте, что у Вас есть массив, состоящий из двух элементов, например:

    Особенность массивов в языке c# заключается в том, что начальный индекс элемента всегда равен нулю. То есть в данном примере, не смотря на то, что число пять — это первое значение элемента массива, при обращении к нему потребуется указать индекс ноль. Так же и для числа семь, несмотря на то, что это число является вторым элементом массива, его индекс так же будет на единицу меньше, то есть, равен одному.

    Обращение к элементам массива:

    Результат: a = 5 и b = 7.

    Но, стоит только указать неверный индекс, например:

    В результате получаем исключение: Index was outside the bounds of the array, то есть индекс находиться за границами диапазона, который в данном примере составляет от 0 до 1. Поэтому при возникновении данной ошибки, первое, что нужно сделать, так это убедиться в том, что Вы указали правильный индекс при обращении к элементу массива или обобщённой коллекции.

    Exception

    Так же данная ошибка очень часто встречается в циклах, особенно в цикле for, если Вы указываете неверное количество элементов содержащихся в массиве, например:

    В результате так же возникает ArgumentOutOfRangeException, так как количество элементов равно двум, а не трём. Поэтому лучше всего в циклах использовать уже готовые методы для подсчёта количества элементов массива или коллекций, например:

    Говоря про циклы нельзя не упомянуть ещё одну ошибку, которая очень часто встречается у многих начинающих программистов. Представим, что у нас есть две коллекции и нам нужно заполнить список var2 значениями из первого списка.

    Не смотря на то, что вроде бы все указано, верно, в результате выполнения кода, уже на самом первом шаге цикла, будет выдано исключение: Index was out of range. Это связано с тем, что для заполнения коллекции var2 требуется использовать не индекс, а метод Add.

    Если же Вы хотите отловить данное исключение, в ходе выполнения программы, то для этого достаточно воспользоваться блоками try catch, например:

    Index Out OfRange Exception Класс

    Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

    Исключение, возникающее при попытке обращения к элементу массива или коллекции с индексом, который находится вне границ.

    Комментарии

    Исключение IndexOutOfRangeException возникает, когда недопустимый индекс используется для доступа к члену массива или коллекции, а также для чтения или записи из определенного расположения в буфере. Это исключение наследует от Exception класса, но не добавляет уникальных членов.

    Как правило, IndexOutOfRangeException исключение возникает в результате ошибки разработчика. Вместо обработки исключения следует диагностировать причину ошибки и исправить код. Наиболее распространенными причинами ошибки являются:

    Забывая, что верхняя граница коллекции или отсчитываемого от нуля массива меньше, чем его количество элементов или элементов, как показано в следующем примере.

    Чтобы исправить ошибку, можно использовать код, как показано ниже.

    Кроме того, вместо итерации всех элементов массива по их индексу можно использовать foreach инструкцию (в C#), for. in инструкцию (в F#) или инструкцию For Each (в Visual Basic).

    Попытка назначить элемент массива другому массиву, который не был адекватно измерен и имеет меньше элементов, чем исходный массив. В следующем примере предпринимается попытка назначить последний элемент массива value1 тому же элементу в массиве value2 . value2 Однако массив был неправильно измерен, чтобы иметь шесть вместо семи элементов. В результате назначение создает IndexOutOfRangeException исключение.

    Использование значения, возвращаемого методом поиска, для итерации части массива или коллекции, начиная с определенной позиции индекса. Если вы забыли проверить, найдена ли операция поиска совпадения, среда выполнения создает IndexOutOfRangeException исключение, как показано в этом примере.

    В этом случае List<T>.IndexOf метод возвращает значение -1, которое является недопустимым значением индекса, если не удается найти совпадение. Чтобы исправить эту ошибку, проверьте возвращаемое значение метода поиска перед итерации массива, как показано в этом примере.

    Попытка использовать или перечислить результирующий набор, коллекцию или массив, возвращаемые запросом, не проверяя, имеет ли возвращенный объект допустимые данные.

    Использование вычисляемого значения для определения начального индекса, конечного индекса или числа элементов для итерации. Если результат вычисления непредвиден, это может привести к исключению IndexOutOfRangeException . Необходимо проверить логику программы при вычислении значения индекса и проверить значение перед итерированием массива или коллекции. Все следующие условия должны быть верными; IndexOutOfRangeException В противном случае возникает исключение:

    Начальный индекс должен быть больше или равен Array.GetLowerBound измерению массива, который требуется выполнить итерацию, или больше или равен 0 для коллекции.

    Конечный индекс не может превышать Array.GetUpperBound размер массива, который требуется выполнить итерацию, или не может быть больше или равен Count свойству коллекции.

    Для измерения массива, который требуется выполнить итерацию, должно быть верно следующее уравнение:

    Для коллекции должно быть верно следующее уравнение:

    Начальный индекс массива или коллекции никогда не может быть отрицательным числом.

    Предположим, что массив должен быть отсчитывается от нуля. Массивы, которые не основаны на нулях, могут быть созданы методом Array.CreateInstance(Type, Int32[], Int32[]) и могут быть возвращены COM-взаимодействием, хотя они не соответствуют CLS. В следующем примере показано, что возникает IndexOutOfRangeException при попытке выполнить итерацию массива, отличного от нуля, созданного методом Array.CreateInstance(Type, Int32[], Int32[]) .

    Чтобы исправить ошибку, как показано в следующем примере, можно вызвать GetLowerBound метод вместо предположения о начальном индексе массива.

    Обратите внимание, что при вызове GetLowerBound метода для получения начального индекса массива необходимо также вызвать Array.GetUpperBound(Int32) метод, чтобы получить его конечный индекс.

    Запутывая индекс и значение этого индекса в числовом массиве или коллекции. Эта проблема обычно возникает при использовании инструкции foreach (в C#), for. in инструкции (в F#) или For Each инструкции (в Visual Basic). В следующем примере показана эта проблема.

    Конструкция итерации возвращает каждое значение в массиве или коллекции, а не его индекс. Чтобы исключить исключение, используйте этот код.

    Указание недопустимого имени столбца свойству DataView.Sort .

    Нарушение безопасности потоков. Такие операции, как чтение из одного объекта, запись в один и тот же StreamReader StreamWriter объект из нескольких потоков или перечисление объектов в Hashtable разных потоках могут вызывать исключение IndexOutOfRangeException , если объект недоступит потокобезопасным способом. Это исключение обычно периодически, так как оно зависит от состояния гонки.

    Использование жестко заданных значений индекса для управления массивом, скорее всего, вызовет исключение, если значение индекса неверно или недопустимо, или если размер массива является непредвиденным. Чтобы предотвратить исключение IndexOutOfRangeException , можно сделать следующее:

    Выполните итерацию элементов массива с помощью оператора foreach (в C#), for. оператор in (в F#) или for Each. Следующая конструкция (в Visual Basic) вместо итерации элементов по индексу.

    Итерация элементов по индексу, начиная с индекса, возвращаемого Array.GetLowerBound методом, и заканчивается индексом, возвращаемым методом Array.GetUpperBound .

    Если вы назначаете элементы в одном массиве другому, убедитесь, что целевой массив содержит по крайней мере столько элементов, сколько исходный массив, сравнивая их Array.Length свойства.

    Список начальных значений свойств для экземпляра IndexOutOfRangeException, см. в разделе IndexOutOfRangeException конструкторы.

    Следующие инструкции промежуточного языка (IL) вызывают следующее:IndexOutOfRangeException

    IndexOutOfRangeException использует COR_E_INDEXOUTOFRANGE HRESULT, имеющий значение 0x80131508.

    Конструкторы

    Инициализирует новый экземпляр класса IndexOutOfRangeException.

    Инициализирует новый экземпляр класса IndexOutOfRangeException с указанным сообщением об ошибке.

    Инициализирует новый экземпляр класса IndexOutOfRangeException указанным сообщением об ошибке и ссылкой на внутреннее исключение, вызвавшее данное исключение.

    Свойства

    Возвращает коллекцию пар «ключ-значение», предоставляющую дополнительные сведения об исключении.

    Получает или задает ссылку на файл справки, связанный с этим исключением.

    Возвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению.

    Возвращает экземпляр класса Exception, который вызвал текущее исключение.

    Возвращает сообщение, описывающее текущее исключение.

    Возвращает или задает имя приложения или объекта, вызывавшего ошибку.

    Получает строковое представление непосредственных кадров в стеке вызова.

    Возвращает метод, создавший текущее исключение.

    Методы

    Определяет, равен ли указанный объект текущему объекту.

    При переопределении в производном классе возвращает исключение Exception, которое является первопричиной одного или нескольких последующих исключений.

    Служит хэш-функцией по умолчанию.

    При переопределении в производном классе задает объект SerializationInfo со сведениями об исключении.

    Возвращает тип среды выполнения текущего экземпляра.

    Создает неполную копию текущего объекта Object.

    Создает и возвращает строковое представление текущего исключения.

    События

    Возникает, когда исключение сериализовано для создания объекта состояния исключения, содержащего сериализованные данные об исключении.

    The only thing I can think of is that my program is checking coordinates of < 0? How do I go about fixing this?

    5 Answers 5

    Your first coordinates are parentGen[-1, -1], this will always throw the exception.

    You need to check if the cell you’re on has any neighbors to the left, right, top, or bottom. For example, x = 0 has no neighbors to the left and y = 20 has no neighbors to the bottom. You may wish to break this out to other functions, such as HasNeighborsLeft(int x), etc.

    edit: sample code

    You can factor this out to it’s own functions though, and you can wrap this kind of logic around all of the checks that involve x — 1 for example.

    You need boundary condition checks on both x and y at top and bottom of their range. You cannot legally index the entire array using +1 and -1 offsets. Break up your check into boundary condition cases where x == 0 , x == arrayRows-1 (by not checking the invalid relative offsets here), and then check cases where x+1 and x-1 are always valid in an else . Similarly with y.

    user avatar

    You’re array goes from 0->21. As well, you’re testing values at [-1, -1] and [22, 22]You can fix it by chainging your for statement(s) to

    In addition, problems with loops are almost always caused by a small number of cases that you can always check for:

    Your for statement a) starts at a lower bound than the array, or b) finishes at a higher one a) for (int x = -1; b) for (int x = 0; x <= array.Length

    Your code in the loop accesses values outside of your indexer range for (int x = 0. array[x-1, .

    Your collection isn’t initialized

    In this case, your problem 2.

    The problem is that you are looking at the previous and next values (-1 and +1) which will obviously go outside the array bounds at either ends of the array.

    There are a few options solving this:

    • Create a bigger array with a dummy ‘border’ around the edge which you don’t use for your board but allows you to use code very similar to that which you have now (with your -1 and +1 previous and next cell logic). (Imagine a chess board that is 10×10 where you are not allowed to play in the outermost squares).
    • Scatter loads of ‘if’ statements to check if you’re at the first or last item in the array and thus avoid making any array accesses that are invalid.
    • Create a function to retrieve an item at a particular cell and put conditional logic in this function for dealing with the array bounds.

    Personally I would go with the last option, build yourself a function which gets the state of the specified cell, checks that the indices are valid and returns a default value if they are not. For example:

    It is then simply a matter of swapping your direct accesses to parentGen with calls to the function.

    что это?

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

    Когда Его Бросают

    Учитывая массив, объявленный как:

     byte[] array = new byte[4];
     

    Вы можете получить доступ к этому массиву от 0 до 3, значения за пределами этого диапазона приведут IndexOutOfRangeException к выбрасыванию. Помните об этом при создании массива и доступе к нему.

    Длина Массива
    В C#, как правило, массивы основаны на 0. Это означает, что первый элемент имеет индекс 0, а последний элемент имеет индекс Length - 1 (где Length общее количество элементов в массиве), поэтому этот код не работает:

     array[array.Length] = 0;
     

    Кроме того, пожалуйста, обратите внимание, что если у вас есть многомерный массив, то вы не можете использовать Array.Length оба измерения, вы должны использовать Array.GetLength() :

     int[,] data = new int[10, 5];
    for (int i=0; i < data.GetLength(0);   i) {
        for (int j=0; j < data.GetLength(1);   j) {
            data[i, j] = 1;
        }
    }
     

    Верхняя Граница Не Включает
    В следующем примере мы создаем необработанный двумерный массив Color . Каждый элемент представляет собой пиксель, индексы-от (0, 0) до (imageWidth - 1, imageHeight - 1) .

     Color[,] pixels = new Color[imageWidth, imageHeight];
    for (int x = 0; x <= imageWidth;   x) {
        for (int y = 0; y <= imageHeight;   y) {
            pixels[x, y] = backgroundColor;
        }
    }
     

    This code will then fail because array is 0-based and last (bottom-right) pixel in the image is pixels[imageWidth - 1, imageHeight - 1] :

     pixels[imageWidth, imageHeight] = Color.Black;
     

    In another scenario you may get ArgumentOutOfRangeException for this code (for example if you’re using GetPixel method on a Bitmap class).

    Arrays Do Not Grow
    An array is fast. Very fast in linear search compared to every other collection. It is because items are contiguous in memory so memory address can be calculated (and increment is just an addition). No need to follow a node list, simple math! You pay this with a limitation: they can’t grow, if you need more elements you need to reallocate that array (this may take a relatively long time if old items must be copied to a new block). You resize them with Array.Resize<T>() , this example adds a new entry to an existing array:

     Array.Resize(ref array, array.Length   1);
     

    Don’t forget that valid indices are from 0 to Length - 1 . If you simply try to assign an item at Length you’ll get IndexOutOfRangeException (this behavior may confuse you if you think they may increase with a syntax similar to Insert method of other collections).

    Special Arrays With Custom Lower Bound
    First item in arrays has always index 0. This is not always true because you can create an array with a custom lower bound:

     var array = Array.CreateInstance(typeof(byte), new int[] { 4 }, new int[] { 1 });
     

    In that example, array indices are valid from 1 to 4. Of course, upper bound cannot be changed.

    Wrong Arguments
    If you access an array using unvalidated arguments (from user input or from function user) you may get this error:

     private static string[] RomanNumbers =
        new string[] { "I", "II", "III", "IV", "V" };
    
    public static string Romanize(int number)
    {
        return RomanNumbers[number];
    }
     

    Unexpected Results
    This exception may be thrown for another reason too: by convention, many search functions will return -1 (nullables has been introduced with .NET 2.0 and anyway it’s also a well-known convention in use from many years) if they didn’t find anything. Let’s imagine you have an array of objects comparable with a string. You may think to write this code:

     // Items comparable with a string
    Console.WriteLine("First item equals to 'Debug' is '{0}'.",
        myArray[Array.IndexOf(myArray, "Debug")]);
    
    // Arbitrary objects
    Console.WriteLine("First item equals to 'Debug' is '{0}'.",
        myArray[Array.FindIndex(myArray, x => x.Type == "Debug")]);
     

    This will fail if no items in myArray will satisfy search condition because Array.IndexOf() will return -1 and then array access will throw.

    Next example is a naive example to calculate occurrences of a given set of numbers (knowing maximum number and returning an array where item at index 0 represents number 0, items at index 1 represents number 1 and so on):

     static int[] CountOccurences(int maximum, IEnumerable<int> numbers) {
        int[] result = new int[maximum   1]; // Includes 0
    
        foreach (int number in numbers)
              result[number];
    
        return resu<
    }
     

    Конечно, это довольно ужасная реализация, но я хочу показать, что она не сработает для отрицательных чисел и чисел выше maximum .

    Как это относится к List<T> ?

    Те же случаи, что и массив — диапазон допустимых индексов — 0 ( List индексы всегда начинаются с 0) для list.Count доступа к элементам за пределами этого диапазона, вызовут исключение.

    Обратите внимание, что List<T> броски ArgumentOutOfRangeException выполняются для тех же случаев, когда используются массивы IndexOutOfRangeException .

    В отличие от массивов, List<T> запускается пустым — поэтому попытка доступа к элементам только что созданного списка приводит к этому исключению.

     var list = new List<int>();
     

    Распространенным случаем является заполнение списка индексированием (аналогично Dictionary<int, T> ), что приведет к исключению:

     list[0] = 42; // exception
    list.Add(42); // correct
     

    IDataReader и столбцы
    Представьте, что вы пытаетесь прочитать данные из базы данных с помощью этого кода:

     using (var connection = CreateConnection()) {
        using (var command = connection.CreateCommand()) {
            command.CommandText = "SELECT MyColumn1, MyColumn2 FROM MyTable";
    
            using (var reader = command.ExecuteReader()) {
                while (reader.Read()) {
                    ProcessData(reader.GetString(2)); // Throws!
                }
            }
        }
    }
     

    GetString() выбросит, IndexOutOfRangeException потому что ваш набор данных содержит только два столбца, но вы пытаетесь получить значение из 3-го (индексы всегда основаны на 0).

    Пожалуйста, обратите внимание, что это поведение является общим для большинства IDataReader реализаций ( SqlDataReader OleDbDataReader и так далее).

    Вы также можете получить такое же исключение, если используете перегрузку IDataReader оператора индексатора, который принимает имя столбца и передает недопустимое имя столбца.
    Предположим, например, что вы получили столбец с именем Column1, но затем пытаетесь получить значение этого поля с помощью

      var data = dr["Colum1"];  // Missing the n in Column1.
     

    Это происходит потому, что оператор индексатора реализован при попытке получить индекс несуществующего поля Colum1. Метод GetOrdinal вызовет это исключение, когда его внутренний вспомогательный код вернет значение -1 в качестве индекса «Colum1».

    Прочее
    Существует еще один (задокументированный) случай, когда возникает это исключение: если DataView имя столбца данных, указанное в DataViewSort свойстве , недопустимо.

    Как избежать

    В этом примере позвольте мне для простоты предположить, что массивы всегда одномерны и основаны на 0. Если вы хотите быть строгим (или вы разрабатываете библиотеку), вам, возможно, потребуется заменить 0 на GetLowerBound(0) и .Length с GetUpperBound(0) (конечно, если у вас есть параметры типа System.Arra y, это не применимо T[] ). Пожалуйста, обратите внимание, что в этом случае верхняя граница включена, тогда этот код:

     for (int i=0; i < array.Length;   i) { }
     

    Должно быть переписано вот так:

     for (int i=array.GetLowerBound(0); i <= array.GetUpperBound(0);   i) { }
     

    Пожалуйста, обратите внимание, что это запрещено (это приведет InvalidCastException к сбою), поэтому, если ваши параметры T[] соответствуют, вы можете быть уверены в пользовательских массивах с нижней границей:

     void foo<T>(T[] array) { }
    
    void test() {
        // This will throw InvalidCastException, cannot convert Int32[] to Int32[*]
        foo((int)Array.CreateInstance(typeof(int), new int[] { 1 }, new int[] { 1 }));
    }
     

    Validate Parameters
    If index comes from a parameter you should always validate them (throwing appropriate ArgumentException or ArgumentOutOfRangeException ). In the next example, wrong parameters may cause IndexOutOfRangeException , users of this function may expect this because they’re passing an array but it’s not always so obvious. I’d suggest to always validate parameters for public functions:

     static void SetRange<T>(T[] array, int from, int length, Func<i, T> function)
    {
        if (from < 0 || from>= array.Length)
            throw new ArgumentOutOfRangeException("from");
    
        if (length < 0)
            throw new ArgumentOutOfRangeException("length");
    
        if (from   length > array.Length)
            throw new ArgumentException("...");
    
        for (int i=from; i < from   length;   i)
            array[i] = function(i);
    }
     

    If function is private you may simply replace if logic with Debug.Assert() :

     Debug.Assert(from >= 0 amp;amp; from < array.Length);
     

    Check Object State
    Array index may not come directly from a parameter. It may be part of object state. In general is always a good practice to validate object state (by itself and with function parameters, if needed). You can use Debug.Assert() , throw a proper exception (more descriptive about the problem) or handle that like in this example:

     class Table {
        public int SelectedIndex { get; set; }
        public Row[] Rows { get; set; }
    
        public Row SelectedRow {
            get {
                if (Rows == null)
                    throw new InvalidOperationException("...");
    
                // No or wrong selection, here we just return null for
                // this case (it may be the reason we use this property
                // instead of direct access)
                if (SelectedIndex < 0 || SelectedIndex >= Rows.Length)
                    return null;
    
                return Rows[SelectedIndex];
            }
    }
     

    Validate Return Values
    In one of previous examples we directly used Array.IndexOf() return value. If we know it may fail then it’s better to handle that case:

     int index = myArray[Array.IndexOf(myArray, "Debug");
    if (index != -1) { } else { }
     

    How to Debug

    In my opinion, most of the questions, here on SO, about this error can be simply avoided. The time you spend to write a proper question (with a small working example and a small explanation) could easily much more than the time you’ll need to debug your code. First of all, read this Eric Lippert’s blog post about debugging of small programs, I won’t repeat his words here but it’s absolutely a must read.

    You have source code, you have exception message with a stack trace. Go there, pick right line number and you’ll see:

     array[index] = newValue;
     

    You found your error, check how index increases. Is it right? Check how array is allocated, is coherent with how index increases? Is it right according to your specifications? If you answer yes to all these questions, then you’ll find good help here on StackOverflow but please first check for that by yourself. You’ll save your own time!

    A good start point is to always use assertions and to validate inputs. You may even want to use code contracts. When something went wrong and you can’t figure out what happens with a quick look at your code then you have to resort to an old friend: debugger. Just run your application in debug inside Visual Studio (or your favorite IDE), you’ll see exactly which line throws this exception, which array is involved and which index you’re trying to use. Really, 99% of the times you’ll solve it by yourself in a few minutes.

    Если это произойдет в производстве, то вам лучше добавить утверждения в инкриминируемый код, вероятно, мы не увидим в вашем коде того, чего вы не видите сами (но вы всегда можете поспорить).

    В VB.NET сторона этой истории

    Все, что мы сказали в ответе на C#, справедливо для VB.NET с очевидными различиями в синтаксисе, но есть важный момент, который следует учитывать, когда вы имеете дело с VB.NET массивы.

    В VB.NET, массивы объявляются, устанавливая максимальное допустимое значение индекса для массива. Это не количество элементов, которые мы хотим сохранить в массиве.

     ' declares an array with space for 5 integer 
    ' 4 is the maximum valid index starting from 0 to 4
    Dim myArray(4) as Integer
     

    Таким образом, этот цикл заполнит массив 5 целыми числами, не вызывая исключения IndexOutOfRangeException

     For i As Integer = 0 To 4
        myArray(i) = i
    Next
     

    В VB.NET правило

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

    Понравилась статья? Поделить с друзьями:
  • Index exceeds matrix dimensions матлаб как исправить
  • Index error tuple index out of range
  • Index error string index out of range
  • Index does not exist index valho как исправить ошибку
  • Index 25 size 5 minecraft ошибка