【问题标题】:Will this ever result in a stack overflow error?这会导致堆栈溢出错误吗?
【发布时间】:2011-02-08 03:14:04
【问题描述】:

增加对象的实例变量会导致堆栈溢出错误吗?

例如:

这个方法(java)会导致栈溢出错误:

class StackOverflow {
    public static void StackOverflow (int x) 
    {
        System.out.println (x) ; 
        StackOverflow(x+1) ; 
    } 

    public static void main (String[]arg) { StackOverflow (0) ; 
} 

但这会吗?:(.....是我为了缩短代码而设置的一个空白。它已经足够长了。)

import java.util.*;
class Dice 
{ 
    String name ; 
    int x ; 
    int[] sum ;  

....

public Dice (String name) 
{ 
    this.name = name ; 
    this.x = 0 ; 
    this.sum = new int[7] ; 
}

....

public static void main (String[] arg) 
{
    Dice a1 = new Dice ("a1") ; 
    for (int i = 0; i<6000000; i++) 
    {
        a1.roll () ;
        printDice(a1) ; 
    } 
}

....

    public void roll () 
    {
        this.x = randNum(1, this.sum.length) ; 
        this.sum[x] ++ ;
    }

    public static int randNum (int a, int b) 
    {
        Random random = new Random() ;
        int c = (b-a) ;
        int randomNumber = ((random.nextInt(c)) + a) ;
        return randomNumber ;
    }

    public static void printDice (Dice Dice) 
    { 
        System.out.println (Dice.name) ; 
        System.out.println ("value: "+Dice.x) ; 
        printValues (Dice) ; 
    } 

    public static void printValues (Dice Dice) 
    { 
        for (int i = 0; i<Dice.sum.length; i++) 
        System.out.println ("#of "+i+"'s: "+Dice.sum[i]) ; 
    } 

}

上述内容目前不会导致堆栈溢出错误,但如果我在 main:for (int i = 0; i&lt;6000000; i++) 中更改这一行,我是否也能得到它,这样就可以代替 600 万个足够高的东西?

【问题讨论】:

  • public class StackOverflow { public static void main(String... args) { main(null); } } 现在,that 是StackOverflowError ;)
  • 这个问题的意义何在?简单来说:因为应用递归太深,导致堆栈溢出时抛出堆栈溢出。
  • 我敢打赌,如果你通过传递一个 JVM 选项来更改“堆栈最小大小”,那么你可以让骰子滚轮来处理更多的迭代。
  • @ring bearer:虽然大多数时候 StackOverflow 是由深度递归引起的,但这绝对不是唯一的原因:如果你有数千种不同的方法堆叠在一起,它也可能导致 StackOverflow .
  • 为什么不自己试试看呢?

标签: java recursion stack-overflow


【解决方案1】:

堆栈溢出?不,但它可能导致整数溢出,这是完全不同的事情。

堆栈溢出意味着方法调用堆栈上的空间已用尽(可能是由于递归调用失控)。如果增量超过其最大值,整数溢出将导致 int 循环到其最小值。

【讨论】:

  • 当整数的值变得太大而类型无法容纳时。对于int(带符号的 32 位整数),大约是两亿。
  • 我对网站名称有了新的想法。
  • @David:特别是在 java 中,一个 int 可以保存介于 -2,147,483,648 和 2,147,483,647 之间的任何值。如果您尝试存储更大的数字,则称为整数溢出。如果您尝试存储较小的数字,则称为整数下溢。
  • 我不认为“整数溢出”具有完全相同的环......也许是“下溢”,但这听起来很糟糕而且令人失望。 =P
【解决方案2】:

在 Java 中,堆栈溢出错误来自过多的recursion。这是函数直接或间接调用自身的地方。

在您的第一个示例中,StackOverflow 函数直接调用自身而不受限制。

在您的 Dice 示例中,没有函数调用自身的实例,因此您不太可能遇到堆栈溢出错误。

【讨论】:

  • 函数不再调用自身的特定条件。递归是完全可以的,但递归的层次太深就不行了。
  • 没有递归停止的条件。
【解决方案3】:

堆栈溢出错误是由无限递归引起的,即方法调用自身次数过多。您的第二个代码示例似乎根本没有使用递归,所以我认为不可能出现堆栈溢出错误。

【讨论】:

    【解决方案4】:

    这会导致堆栈吗 溢出错误?

    • 是的

    简单地说:

    当由于应用程序递归太深而发生堆栈溢出时引发堆栈溢出。 这意味着您的行 StackOverflow(x+1) ; 可能会引发堆栈溢出错误,具体取决于您的堆栈有多大。除此之外,代码将开始获得意外的 int 值。

    【讨论】:

      【解决方案5】:

      嗯,您可以使用 -Xss 开关更改 Java 中堆栈的最大大小。最小的堆栈大约为 1KB,因此您不需要无限(甚至非常多)递归来获得所需的堆栈溢出,但您肯定需要比您在示例中给出的更多。我想我的观点是递归足以导致堆栈溢出,但不是必需的;使用任意小的调用堆栈,您可以使用任意少量的方法调用使其溢出。

      【讨论】:

        【解决方案6】:

        这将导致整数溢出,因为 int 类型从大约。 -2E7 到 2E7

        【讨论】:

        • 不正确,int 可以保存介于 -2^31 = -2,147,483,648 和 2^31 - 1 = 2,147,483,647(含)之间的值。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-12
        • 2014-12-20
        • 1970-01-01
        • 2020-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多