how to fix "Index was outside the bounds of the array" [duplicate] - vb.net
I have some code and when it executes, it throws a IndexOutOfRangeException, saying,
Index was outside the bounds of the array.
What does this mean, and what can I do about it?
Depending on classes used it can also be ArgumentOutOfRangeException
An exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll but was not handled in user code Additional information: Index was out of range. Must be non-negative and less than the size of the collection.
What Is It?
This exception means that you're trying to access a collection item by index, using an invalid index. An index is invalid when it's lower than the collection's lower bound or greater than or equal to the number of elements it contains.
When It Is Thrown
Given an array declared as:
byte[] array = new byte[4];
You can access this array from 0 to 3, values outside this range will cause IndexOutOfRangeException to be thrown. Remember this when you create and access an array.
Array Length
In C#, usually, arrays are 0-based. It means that first element has index 0 and last element has index Length - 1 (where Length is total number of items in the array) so this code doesn't work:
array[array.Length] = 0;
Moreover please note that if you have a multidimensional array then you can't use Array.Length for both dimension, you have to use 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;
}
}
Upper Bound Is Not Inclusive
In the following example we create a raw bidimensional array of Color. Each item represents a pixel, indices are from (0, 0) to (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 result;
}
Of course, it's a pretty terrible implementation but what I want to show is that it'll fail for negative numbers and numbers above maximum.
How it applies to List<T>?
Same cases as array - range of valid indexes - 0 (List's indexes always start with 0) to list.Count - accessing elements outside of this range will cause the exception.
Note that List<T> throws ArgumentOutOfRangeException for the same cases where arrays use IndexOutOfRangeException.
Unlike arrays, List<T> starts empty - so trying to access items of just created list lead to this exception.
var list = new List<int>();
Common case is to populate list with indexing (similar to Dictionary<int, T>) will cause exception:
list[0] = 42; // exception
list.Add(42); // correct
IDataReader and Columns
Imagine you're trying to read data from a database with this code:
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() will throw IndexOutOfRangeException because you're dataset has only two columns but you're trying to get a value from 3rd one (indices are always 0-based).
Please note that this behavior is shared with most IDataReader implementations (SqlDataReader, OleDbDataReader and so on).
You can get the same exception also if you use the IDataReader overload of the indexer operator that takes a column name and pass an invalid column name.
Suppose for example that you have retrieved a column named Column1 but then you try to retrieve the value of that field with
var data = dr["Colum1"]; // Missing the n in Column1.
This happens because the indexer operator is implemented trying to retrieve the index of a Colum1 field that doesn't exist. The GetOrdinal method will throw this exception when its internal helper code returns a -1 as the index of "Colum1".
Others
There is another (documented) case when this exception is thrown: if, in DataView, data column name being supplied to the DataViewSort property is not valid.
How to Avoid
In this example, let me assume, for simplicity, that arrays are always monodimensional and 0-based. If you want to be strict (or you're developing a library), you may need to replace 0 with GetLowerBound(0) and .Length with GetUpperBound(0) (of course if you have parameters of type System.Array, it doesn't apply for T[]). Please note that in this case, upper bound is inclusive then this code:
for (int i=0; i < array.Length; ++i) { }
Should be rewritten like this:
for (int i=array.GetLowerBound(0); i <= array.GetUpperBound(0); ++i) { }
Please note that this is not allowed (it'll throw InvalidCastException), that's why if your parameters are T[] you're safe about custom lower bound arrays:
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 && 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.
If this happens in production then you'd better to add assertions in incriminated code, probably we won't see in your code what you can't see by yourself (but you can always bet).
The VB.NET side of the story
Everything that we have said in the C# answer is valid for VB.NET with the obvious syntax differences but there is an important point to consider when you deal with VB.NET arrays.
In VB.NET, arrays are declared setting the maximum valid index value for the array. It is not the count of the elements that we want to store in the array.
' declares an array with space for 5 integer
' 4 is the maximum valid index starting from 0 to 4
Dim myArray(4) as Integer
So this loop will fill the array with 5 integers without causing any IndexOutOfRangeException
For i As Integer = 0 To 4
myArray(i) = i
Next
The VB.NET rule
This exception means that you're trying to access a collection item by index, using an invalid index. An index is invalid when it's lower than the collection's lower bound or greater than equal to the number of elements it contains. the maximum allowed index defined in the array declaration
Simple explanation about what a Index out of bound exception is:
Just think one train is there its compartments are D1,D2,D3.
One passenger came to enter the train and he have the ticket for D4.
now what will happen. the passenger want to enter a compartment that does not exist so obviously problem will arise.
Same scenario: whenever we try to access an array list, etc. we can only access the existing indexes in the array. array[0] and array[1] are existing. If we try to access array[3], it's not there actually, so an index out of bound exception will arise.
To easily understand the problem, imagine we wrote this code:
static void Main(string[] args)
{
string[] test = new string[3];
test[0]= "hello1";
test[1]= "hello2";
test[2]= "hello3";
for (int i = 0; i <= 3; i++)
{
Console.WriteLine(test[i].ToString());
}
}
Result will be:
hello1
hello2
hello3
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
Size of array is 3 (indices 0, 1 and 2), but the for-loop loops 4 times (0, 1, 2 and 3). So when it tries to access outside the bounds with (3) it throws the exception.
A side from the very long complete accepted answer there is an important point to make about IndexOutOfRangeException compared with many other exception types, and that is:
Often there is complex program state that maybe difficult to have control over at a particular point in code e.g a DB connection goes down so data for an input cannot be retrieved etc... This kind of issue often results in an Exception of some kind that has to bubble up to a higher level because where it occurs has no way of dealing with it at that point.
IndexOutOfRangeException is generally different in that it in most cases it is pretty trivial to check for at the point where the exception is being raised. Generally this kind of exception get thrown by some code that could very easily deal with the issue at the place it is occurring - just by checking the actual length of the array. You don't want to 'fix' this by handling this exception higher up - but instead by ensuring its not thrown in the first instance - which in most cases is easy to do by checking the array length.
Another way of putting this is that other exceptions can arise due to genuine lack of control over input or program state BUT IndexOutOfRangeException more often than not is simply just pilot (programmer) error.
These two exceptions are common in various programming languages and as others said it's when you access an element with an index greater than the size of the array. For example:
var array = [1,2,3];
/* var lastElement = array[3] this will throw an exception, because indices
start from zero, length of the array is 3, but its last index is 2. */
The main reason behind this is compilers usually don't check this stuff, hence they will only express themselves at runtime.
Similar to this:
Why don't modern compilers catch attempts to make out-of-bounds access to arrays?
Related
MutableList of MutableLists in Kotlin: adding element error
Why I'm getting "java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0" while running next code??? : val totalList = mutableListOf<MutableList<Int>>() fun main() { for (i in 0..15) { for (j in 0..10) { *some operations and calculations with **var element of type Int*** totalList[i].add(element) } } } I was thinking that in such case while iterating through 'j' it should add elements to mutableList[i], after this it should start adding elements to mutableList[i + 1] etc.... But instead I am recieving IndexOutOfBoundsException....
val totalList = mutableListOf<MutableList<Int>>() All this does is create one list which is going to contain MutableList<Int> items. Right now, there's nothing in it (you've supplied no initial elements in the parentheses). Skip forward a bit, and you do this: totalList[0].add(element) You're trying to get the first element of that empty list and add to it. But there is no first element (index 0) because the list is empty (length 0). That's what the error is telling you. There's lots of ways to handle this - one thing you could do is create your lists up-front: // create the 16 list items you want to access in the loop // (the number is the item count, the lambda generates each item) val totalList = MutableList(16) { mutableListOf<Int>() } // then refer to that list's properties in your loop (no hardcoded 0..15) for (i in totalList.indices) { ... // guaranteed to exist since i is generated from the list's indices totalList[i].add(element) } Or you could do it the way you are now, only using getOrElse to generate the empty list on-demand, when you try to get it but it doesn't exist: for (i in 0..15) { for (j in 0..10) { // if the element at i doesn't exist, create a list instead, but also // add it to the main list (see below) totalList.getOrElse(i) { mutableListOf<Int>().also { totalList.add(it) } }.add(element) } } Personally I don't really like this, you're using explicit indices but you're adding new list items to the end of the main list. That implicity requires that you're iterating over the list items in order - which you are here, but there's nothing enforcing that. If the order ever changed, it would break. I'd prefer the first approach - create your structure of lists in advance, then iterate over those and fill them as necessary. Or you might want to consider arrays instead, since you have a fixed collection size you're "completing" by adding items to specific indices Another approach (that I mentioned in the comments) is to create each list as a whole, complete thing, and then add that to your main list. This is generally how you do things in Kotlin - the standard library contains a lot of functional tools to allow you to chain operations together, transform things, and create immutable collections (which are safer and more explicit about whether they're meant to be changed or they're a fixed set of data). for (i in 0..15) { // map transforms each element of the range (each number) to an item, // resulting in a list of items val items = (0..10).map { j -> // do whatever you're doing // the last expression in the lambda is its resulting value, // i.e. the item that ends up in the list element } // now you have a complete list of items, add them to totalList totalList.add(items) } (Or you could create the list directly with List(11) { j -> ... } but this is a more general example of transforming a bunch of things to a bunch of other things) That example there is kinda half and half - you still have the imperative for loop going on as well. Writing it all using the same approach, you can get: val totalList = (0..15).map { i -> (0..10).map { j -> // do stuff element } } I'd probably prefer the List(count) { i -> ... } approach for this, it's a better fit (this is a general example). That would also be better since you could use MutableList instead of List, if you really need them to be mutable (with the maps you could just chain .toMutableList() after the mapping function, as another step in the chain). Generally in Kotlin, collections are immutable by default, and this kind of approach is how you build them up without having to create a mutable list etc. and add items to it yourself
Unable to save data from datagridview [duplicate]
I have some code and when it executes, it throws a IndexOutOfRangeException, saying, Index was outside the bounds of the array. What does this mean, and what can I do about it? Depending on classes used it can also be ArgumentOutOfRangeException An exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll but was not handled in user code Additional information: Index was out of range. Must be non-negative and less than the size of the collection.
What Is It? This exception means that you're trying to access a collection item by index, using an invalid index. An index is invalid when it's lower than the collection's lower bound or greater than or equal to the number of elements it contains. When It Is Thrown Given an array declared as: byte[] array = new byte[4]; You can access this array from 0 to 3, values outside this range will cause IndexOutOfRangeException to be thrown. Remember this when you create and access an array. Array Length In C#, usually, arrays are 0-based. It means that first element has index 0 and last element has index Length - 1 (where Length is total number of items in the array) so this code doesn't work: array[array.Length] = 0; Moreover please note that if you have a multidimensional array then you can't use Array.Length for both dimension, you have to use 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; } } Upper Bound Is Not Inclusive In the following example we create a raw bidimensional array of Color. Each item represents a pixel, indices are from (0, 0) to (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 result; } Of course, it's a pretty terrible implementation but what I want to show is that it'll fail for negative numbers and numbers above maximum. How it applies to List<T>? Same cases as array - range of valid indexes - 0 (List's indexes always start with 0) to list.Count - accessing elements outside of this range will cause the exception. Note that List<T> throws ArgumentOutOfRangeException for the same cases where arrays use IndexOutOfRangeException. Unlike arrays, List<T> starts empty - so trying to access items of just created list lead to this exception. var list = new List<int>(); Common case is to populate list with indexing (similar to Dictionary<int, T>) will cause exception: list[0] = 42; // exception list.Add(42); // correct IDataReader and Columns Imagine you're trying to read data from a database with this code: 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() will throw IndexOutOfRangeException because you're dataset has only two columns but you're trying to get a value from 3rd one (indices are always 0-based). Please note that this behavior is shared with most IDataReader implementations (SqlDataReader, OleDbDataReader and so on). You can get the same exception also if you use the IDataReader overload of the indexer operator that takes a column name and pass an invalid column name. Suppose for example that you have retrieved a column named Column1 but then you try to retrieve the value of that field with var data = dr["Colum1"]; // Missing the n in Column1. This happens because the indexer operator is implemented trying to retrieve the index of a Colum1 field that doesn't exist. The GetOrdinal method will throw this exception when its internal helper code returns a -1 as the index of "Colum1". Others There is another (documented) case when this exception is thrown: if, in DataView, data column name being supplied to the DataViewSort property is not valid. How to Avoid In this example, let me assume, for simplicity, that arrays are always monodimensional and 0-based. If you want to be strict (or you're developing a library), you may need to replace 0 with GetLowerBound(0) and .Length with GetUpperBound(0) (of course if you have parameters of type System.Array, it doesn't apply for T[]). Please note that in this case, upper bound is inclusive then this code: for (int i=0; i < array.Length; ++i) { } Should be rewritten like this: for (int i=array.GetLowerBound(0); i <= array.GetUpperBound(0); ++i) { } Please note that this is not allowed (it'll throw InvalidCastException), that's why if your parameters are T[] you're safe about custom lower bound arrays: 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 && 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. If this happens in production then you'd better to add assertions in incriminated code, probably we won't see in your code what you can't see by yourself (but you can always bet). The VB.NET side of the story Everything that we have said in the C# answer is valid for VB.NET with the obvious syntax differences but there is an important point to consider when you deal with VB.NET arrays. In VB.NET, arrays are declared setting the maximum valid index value for the array. It is not the count of the elements that we want to store in the array. ' declares an array with space for 5 integer ' 4 is the maximum valid index starting from 0 to 4 Dim myArray(4) as Integer So this loop will fill the array with 5 integers without causing any IndexOutOfRangeException For i As Integer = 0 To 4 myArray(i) = i Next The VB.NET rule This exception means that you're trying to access a collection item by index, using an invalid index. An index is invalid when it's lower than the collection's lower bound or greater than equal to the number of elements it contains. the maximum allowed index defined in the array declaration
Simple explanation about what a Index out of bound exception is: Just think one train is there its compartments are D1,D2,D3. One passenger came to enter the train and he have the ticket for D4. now what will happen. the passenger want to enter a compartment that does not exist so obviously problem will arise. Same scenario: whenever we try to access an array list, etc. we can only access the existing indexes in the array. array[0] and array[1] are existing. If we try to access array[3], it's not there actually, so an index out of bound exception will arise.
To easily understand the problem, imagine we wrote this code: static void Main(string[] args) { string[] test = new string[3]; test[0]= "hello1"; test[1]= "hello2"; test[2]= "hello3"; for (int i = 0; i <= 3; i++) { Console.WriteLine(test[i].ToString()); } } Result will be: hello1 hello2 hello3 Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array. Size of array is 3 (indices 0, 1 and 2), but the for-loop loops 4 times (0, 1, 2 and 3). So when it tries to access outside the bounds with (3) it throws the exception.
A side from the very long complete accepted answer there is an important point to make about IndexOutOfRangeException compared with many other exception types, and that is: Often there is complex program state that maybe difficult to have control over at a particular point in code e.g a DB connection goes down so data for an input cannot be retrieved etc... This kind of issue often results in an Exception of some kind that has to bubble up to a higher level because where it occurs has no way of dealing with it at that point. IndexOutOfRangeException is generally different in that it in most cases it is pretty trivial to check for at the point where the exception is being raised. Generally this kind of exception get thrown by some code that could very easily deal with the issue at the place it is occurring - just by checking the actual length of the array. You don't want to 'fix' this by handling this exception higher up - but instead by ensuring its not thrown in the first instance - which in most cases is easy to do by checking the array length. Another way of putting this is that other exceptions can arise due to genuine lack of control over input or program state BUT IndexOutOfRangeException more often than not is simply just pilot (programmer) error.
These two exceptions are common in various programming languages and as others said it's when you access an element with an index greater than the size of the array. For example: var array = [1,2,3]; /* var lastElement = array[3] this will throw an exception, because indices start from zero, length of the array is 3, but its last index is 2. */ The main reason behind this is compilers usually don't check this stuff, hence they will only express themselves at runtime. Similar to this: Why don't modern compilers catch attempts to make out-of-bounds access to arrays?
Kotlin: ArrayList of String type: App crashes on initializing elements through assignment
Basically, this code works: var optionsList = ArrayList<String>() optionsList.add("Alpha") optionsList.add("Bravo") optionsList.add("Charlie") optionsList[2] = "Foxtrot"// Assignment works (only) if initialization has been done previously through add() However, the following makes the application crash (with no compile time errors or warnings): var optionsList = ArrayList<String>(3) optionsList[0] = "Alpha" optionsList[1] = "Bravo" optionsList[2] = "Charlie" This seems unexpected and I can't figure out the reason for the crash. In my understanding, both ways should be equivalent - in the first we are allocating memory for and initializing only one element at a time, whereas in the second we are allocating the memory for all elements together at the beginning and later changing values. Can someone please help me understand what might be going on under the hood here? I have only just started learning Kotlin and have used C++ in the past, so that might be affecting how I am thinking about this.
In Kotlin list[n] is a short hand for list.get(n), and with a assignment operator list[n] = value it is translated to list.set(n, value). The optionsList[2] = "Foxtrot" tries to override the value at 2 and return the old value (that is never null) as defined in KDocs, so if there was no value at that index what will it return? public E set(int index, E element) { Objects.checkIndex(index, size); E oldValue = elementData(index); elementData[index] = element; return oldValue; } It is true that the space is allocated in the memory for the values in var optionsList = ArrayList<String>(3) But since operator fun set(index: Int, element: E): E requires to return the old value which is not possible because the value at that index never existed, so it fails to do the operation. Edit: The point of allocation of space is to reduce the time taken to add a bulk of values, for instance if you wanted to add a large amount of values like 10000 then the pre-allocation (0.6ms) takes around 3.5x less time than dynamically allocated ArrayList (2ms). See: https://pl.kotl.in/iV3ZNNjOC
Modifying self in `iter_mut().map(..)`, aka mutable functional collection operations
How do I convert something like this: let mut a = vec![1, 2, 3, 4i32]; for i in a.iter_mut() { *i += 1; } to a one line operation using map and a closure? I tried: a.iter_mut().map(|i| *i + 1).collect::<Vec<i32>>(); The above only works if I reassign it to a. Why is this? Is map getting a copy of a instead of a mutable reference? If so, how can I get a mutable reference?
Your code dereferences the variable (*i) then adds one to it. Nowhere in there does the original value get changed. The best way to do what you asked is to use Iterator::for_each: a.iter_mut().for_each(|i| *i += 1); This gets an iterator of mutable references to the numbers in your vector. For each item, it dereferences the reference and then increments it. You could use map and collect, but doing so is non-idiomatic and potentially wasteful. This uses map for the side-effect of mutating the original value. The "return value" of assignment is the unit type () - an empty tuple. We use collect::<Vec<()>> to force the Iterator adapter to iterate. This last bit ::<...> is called the turbofish and allows us to provide a type parameter to the collect call, informing it what type to use, as nothing else would constrain the return type.: let _ = a.iter_mut().map(|i| *i += 1).collect::<Vec<()>>(); You could also use something like Iterator::count, which is lighter than creating a Vec, but still ultimately unneeded: a.iter_mut().map(|i| *i += 1).count(); As Ry- says, using a for loop is more idiomatic: for i in &mut a { *i += 1; }
How to test if an item exists in a telerik grid without causing an exception
I have a rad grid bound to a collection of custom objects and occasionally I grab a rows index like this: e.Item.ItemIndexHierarchical at some point later when I want to retrieve that item (if it still exists) I use this: gvAgendaItems.Items(HierarchicalIndexKey) The problem is that sometimes the item doesn't exist anymore - and I'm OK with that - but I'd like to gracefully skip over the section of code that is working on the items it can find. As it stands, searching for an item using a no longer valid key throws an exception so I can't just check if the resulting item is nothing. How can I test if that HierarchicalIndexKey is still valid without throwing an exception?
I don't see any elegant ways to do this in the Telerik documentation (leaving only blunt/inefficient ways, unfortunately). You could loop through the items and match the HierarchicalIndexKey on each item's ItemIndexHierarchical: int i = 0; bool bIndexExists = false; GridDataItem item = null; for (i = 0; i <= gvAgendaItems.Items.Count - 1; i++) { bIndexExists = gvAgendaItems.Items(i).ItemIndexHierarchical == HierarchicalIndexKey; if (bIndexExists) { item = gvAgendaItems.Items(HierarchicalIndexKey); break; } } You could wrap it in a Try/Catch block and simply fail silently. GridDataItem item = null; try { item = gvAgendaItems.Items(HierarchicalIndexKey); } catch (Exception ex) { //fail silently without throwing an exception. } Looping will be more efficient with smaller datasources, where as wrapping will be more efficient with larger datasources (the breakpoint is when it takes more time to loop through the collection than it does to throw an exception). Wish I had a better answer, but I hope this helps.