使用随机数时出现间歇性堆栈溢出异常
本文关键字:堆栈 栈溢出 异常 随机数 | 更新日期: 2023-09-27 18:25:10
public int S1x;
public void Execute()
{
Random random = new Random();
S1x = random.Next(14, 146);
if (S1x % 15 != 0)
Fix(S1x);
}
public int Fix(int SX)
{
Random randomG = new Random();
SX = randomG.Next(14, 146);
if (SX % 15 != 0)
Fix(SX); // This is the recursion
return SX;
}
每隔几次运行它就可以正常工作,但是我会尝试再次编译并运行它,它会给我这个错误:
System.StackOverflowException 是未处理的 mscorlib 中发生了类型为"System.StackOverflowException"的未处理异常.dll {无法计算表达式,因为当前线程处于堆栈溢出状态。
而且,是的,我知道有一种更简单的方法可以做到这一点,但我将值设置为等于 14 到 146 之间的随机数,同时确保它是 15 的倍数的方法仍然有效。
我真的很困惑为什么它有时只给我错误消息。
那么它有什么问题呢?为什么它被标记为无限递归,即使它没有什么无限的?
即使你解决了这个问题——每次根据当前时间创建一个新的 Random 对象——你的代码仍然不正确或高效。请记住,递归方法需要具有以下特征才能正确:
- 一个微不足道的问题可以在没有递归的情况下解决
- 递归步骤使问题更小
- 有限数量的递归总是将问题简化为一个微不足道的问题
您没有任何这些属性,因此递归是错误的解决方案。
如果你想要一个介于 14 和 146 之间的随机数,并且是 15 的倍数,则不需要任何递归。唯一的数字是15、30、45、60、75、90、105、120和135。所以就说:
private int[] array = { 15, 30, 45, 60, 75, 90, 105, 120, 135 };
private Random random = new Random();
...
return array[random.Next(0, array.Length)];
甚至更好:在 1 到 9 之间选择一个随机数,然后将其乘以 15。
return random.Next(1, 10) * 15;
new Random()
用Environment.TickCount
(自系统启动以来的毫秒(为自身播种以生成伪随机数,如果您两次使用相同的数字为其播种,则 rand.Next(x, y);
的第一次调用每次都将返回相同的值。
public int Fix(int SX)
{
Random randomG = new Random();
SX = randomG.Next(14, 146);
if (SX % 15 != 0)
{
Fix(SX); // This is the recursion
}
return SX;
}
由于每次运行此函数(在同一毫秒内(时都会创建一个新的Random
实例,因此它将生成相同的数字。因此,在生成新号码之前,它会被调用数千次。如果这样做:
Random randomG = new Random();
public int Fix(int SX)
{
SX = randomG.Next(14, 146);
if (SX % 15 != 0)
{
Fix(SX); // This is the recursion
}
return SX;
}
至少每次调用它时它都会生成一个新的随机数,这样你就更有可能在堆栈溢出之前击中你想要的随机数。
编辑:我忘了提到为什么递归是实现这一目标的坏主意。实际上不要使用上面的代码,它仍然是一个糟糕的解决方案。我现在不会修改我的答案,因为已经发布了更好的答案