簡體   English   中英

java stackoverflow錯誤

[英]java stackoverflow error

大家好,我正在為一個大學課程開發程序,該程序使用一種稱為get_line()的方法來遞歸計算從網格上的一個點到另一個點的連續位置列表。 當我運行它時,在該方法中最后一個return語句的行上出現堆棧溢出。 我想知道是否可以讓其他人查看該方法,看看是否有什么看起來完全錯誤。 該方法提供如下:

感謝您的幫助!

location是包含行r和列c的對象。

private Vector<location> get_line(location from, location to) {
    location nextLoc = new location();
    Vector<location> loc = new Vector<location>();
    Random r = new Random();

    if(to.r == from.r && to.c == from.c) {
        return(loc);
    } else {
        if(to.r > from.r && to.c > from.c) {
            nextLoc.r = from.r + 1;
            nextLoc.c = from.c + 1;
        } else if(to.r < from.r && to.c < from.c) {
            nextLoc.r = from.r - 1;
            nextLoc.c = from.c - 1;
        } else if(to.r < from.r && to.c > from.c) {
            nextLoc.r = from.r - 1;
            nextLoc.c = from.c + 1;
        } else if(to.r > from.r && to.c < from.c) {
            nextLoc.r = from.r + 1;
            nextLoc.c = from.c - 1;
        } else if(to.r == from.r && to.c > from.c) {
            if(r.nextInt(2) == 0) {
                nextLoc.r = from.r + 1;
            } else {
                nextLoc.r = from.r - 1;
            }
            nextLoc.c = from.c + 1;
        } else if(to.r == from.r && to.c < from.c) {
            if(r.nextInt(2) == 0) {
                nextLoc.r = from.r + 1;
            } else {
                nextLoc.r = from.r - 1;
            }
            nextLoc.c = from.c - 1;
        } else if(to.r < from.r && to.c == from.c) {
            nextLoc.r = from.r - 1;
            if(r.nextInt(2) == 0) {
                nextLoc.c = from.c + 1;
            } else {
                nextLoc.c = from.c - 1;
            }
        } else if(to.r > from.r && to.c == from.c) {
            nextLoc.r = from.r + 1;
            if(r.nextInt(2) == 0) {
                nextLoc.c = from.c + 1;
            } else {
                nextLoc.c = from.c - 1;
            }
        }

        loc.add(nextLoc);

        return(get_line(nextLoc,to)); //stack overflow error occurs here.
    }
}

這兩個參數為真的條件是:

if(to.r == from.r && to.c == from.c)

在我的瀏覽過程中,似乎總是對nextloc進行了修改,因此上述聲明永遠不會成立。

“ to.r == from.r && to.c == from.c”永遠不會評估為真...

如果堆棧溢出,則可能存在無限循環。 換句話說,您的算法永遠找不到“到”點。 嘗試在方法開始時打印出“ nextLoc”值,以查看它是否在匹配方面取得了進展。 然后,您可以嘗試找出算法出了問題的地方。

您在這里有一個遞歸函數。 那是一個自我調用的函數。 每次進行方法調用時,都會向堆棧中添加一個框架。 如果遞歸函數沒有在合理數量的遞歸中退出,則將耗盡堆棧空間。 因此堆棧溢出。 正如其他人所說,您的條件之一似乎總是錯誤的,因此您將無限遞歸(直到耗盡堆棧空間)。 這就像一個無限循環,只是硬件無法處理它,因此它崩潰了,而不是永遠工作。

通過-Xss http://forums.sun.com/thread.jspa?threadID=756468增加運行時堆棧大小

如果您簡化代碼,則可能會更容易看到該問題,因為其中包含不必要的重復。 您的行和列操作可以是獨立的

    if ( to.r > from.r ){
           nextLoc.r = from.r + 1;
    } else if ( to.r < from.r) {
            nextLoc.r = from.r -1;
    }

    if ( to.c > from.c ){
           nextLoc.c = from.c + 1;
    } else if ( to.c < from.c) {
            nextLoc.c = from.c -1;
    }

與同等學歷相比,我發現更容易理解:

    if(to.r > from.r && to.c > from.c) {
        nextLoc.r = from.r + 1;
        nextLoc.c = from.c + 1;
    } else if(to.r < from.r && to.c < from.c) {
        nextLoc.r = from.r - 1;
        nextLoc.c = from.c - 1;
    } else if(to.r < from.r && to.c > from.c) {
        nextLoc.r = from.r - 1;
        nextLoc.c = from.c + 1;
    } else if(to.r > from.r && to.c < from.c) {
        nextLoc.r = from.r + 1;
        nextLoc.c = from.c - 1;

首先,每次輸入方法時,您都在為隨機數生成器植入種子,移動:

Random r = new Random();

到類的屬性。

其次,如果您的方法返回,則它只會返回一個空的Vector,因為您每次都會創建一個新的Vector。

第三,您列舉了8個可能的方向,這些方向使代碼比所需的更加復雜,請嘗試分別處理行和列來重寫它,例如:

if (to.c == from.c && to.r == from.r) {
    // reached destination
    return;
}

if (to.c > from.c) {
    // move right
} else if (to.c < from.c) {
    // move left
} else {
    // random step left/right
}

if (to.r > from.r) {
    // move down
} else if (to.r < from.r) {
    // move up
} else {
    // random step up/down
}

// take next step

編輯 :你的算法,因為它現在只能達到to的位置,如果最后一步是對角線。 如果最后一步是水平的,則始終會垂直轉向,反之亦然,因此,您將無限地徘徊在目標廣告周圍,從而導致堆棧溢出。 一個可行的解決方案是使用nextInt(3)而不是三分之一的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM