'Index was outside the bounds of the array occurs on array initialization?
My program has been working fine for 2 months. But we received this exception today.
The program is multi-thread program. But only one thread use this class.
It is release mode, without Visual Studio.
The exception throws at this line:
int[] list = new int[count]; //Count = 52
The function is:
private static readonly Random _rand = new Random();
public static int[] GetList(int count)
{
int[] list = new int[count]; // this is line 21
for (int i = 0; i < count; i++)
{
list[i] = i;
}
for (int i = 0; i < count * count; i++)
{
int i1 = _rand.Next(count);
int i2 = _rand.Next(count);
if (i1 == i2) continue;
//swap values
list[i1] ^= list[i2];
list[i2] ^= list[i1];
list[i1] ^= list[i2];
}
return list;
}
Part of the log is:
Index was outside the bounds of the array.
at iCulture.GameFramework.Util.RandomList.GetList(Int32 count) in C:\Rm716b\texasgame\TexasHoldem\trunk\iCulture.GameFramework\Util\RandomList.cs:line 21
at iCulture.Texas.Cards..ctor() in C:\Rm716b\texasgame\TexasHoldem\trunk\iCulture.Texas\Cards.cs:line 18
at iCulture.Texas.TexasGame..ctor(Player[] ParticipatePlayers, Int32 SmallBindAmount, Int32 SmallBlindPosition) in C:\Rm716b\texasgame\TexasHoldem\trunk\iCulture.Texas\TexasGame.cs:line 46
I have tried decompiling the DLL, but the code logic remains the same as the original source code.
It is possible hardware error cause this problem? Because it DOES NOT reappear since then.
Solution 1:[1]
The method works fine. I ran it 10000 times, and no errors.
The only thing that I can think of is if you are using this in a multi-threaded application. The Random class is not thread safe, so threads using the same instance could mess up its internal values. In that case each thread should have its own instance of the random generator, and you should send that in as a parameter to the method.
Your method of shuffling the items isn't very efficient. You should use the Fisher.Yates algoritm instead, which is an O(n) operation instead of O(n*n). Also, your method has a slight bias towards the original order, while this has no bias:
public static int[] GetList(int count) {
int[] list = new int[count];
for (int i = 0; i < count; i++) {
list[i] = i;
// swap the item with any previous item, or itself
int swap = _rand.Next(i + 1);
if (swap != i) {
int temp = list[i];
list[i] = list[swap];
list[swap] = temp;
}
}
return list;
}
Solution 2:[2]
I just ran your code and received no exceptions or errors.
This narrows it down to your _rand declaration. Are you specifying a seed value? If so, that could be throwing off your index if it is greater than count.
You should be declaring the _rand class field something like this:
static Random _rand = new Random();
But the code you listed is working code.
Step through your code and see what _rand.Next(count) returns. I guarantee you it's not a usable index for your array.
Solution 3:[3]
Firstly, an IndexOutOfBoundsException cannot be thrown on an array that hasn't been declared yet.
The error is happening in release mode without the debugger attached. This is good to know. Keep in mind that there are major optimizations done by Visual Studio when your code is compiled in release and not attached to a debugger. This leads me to my main point.
YOU ARE BEING MISLED BY THE STACK TRACE
I confirmed this myself, by purposely trying to access an element outside of the array. The stack trace said the error happened on line 36, which for me is: return list; The actual error that I caused, was inserted on line 31.
I doubt the stack trace isn't lying about what function the exception is happening, though. But I would say that the code throwing the exception is probably not the code you see in Visual Studio.
Does the issue happen when you run it in Release mode with the debugger attached?
Open the code in a decompiler, like this one. If you browsed to the method you have above, does the source code match (more or less, a decompiler isn't perfect).
EDIT:
So the code seems to be the same. Either way, the error that you are getting is not happening at the line the stack trace is telling you. There's nothing I can do to help you at this point, since I don't have access to the offending binary.
My suggestion: When the application crashes, use Task Manager to save a dump of the program's memory. (Alternatively, you can use AdPlus or ProcDump, to do it automatically when it crashes). Use WinDbg to open the dump and view the memory, stack trace, and even the jitted methods to try and determine where it actually happened.
Other than that, there's not much you can get from anyone else here on StackOverflow. Bugs like this are a pain, and unfortunately happen every once and a while.
Solution 4:[4]
list[i1] ^= list[i2];
list[i2] ^= list[i1];
list[i1] ^= list[i2];
these lines of codes point to values that might be outside the declaration limit.
The code looks faulty ... what are you trying to achieve ?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | |
| Solution 4 | Naval |
