我實現了一個遞歸算法,它運行約1730年遞歸,然後崩潰與神祕的SIGSEGV。我想我的GDB,得到了以下的輸出:SIGSEGV與遞歸算法
Program received signal SIGSEGV, Segmentation fault.
0x000000000040b7da in Town::get_cur_capacity (this=0x61efe0) at ./solver/Darstellung.cpp:54
54 return left_over_capacity;
(gdb) print 0x61efe0
$1 = 6418400
(gdb) print *0x61efe0
Cannot access memory at address 0x61efe0
(gdb) print this
$2 = (const Town * const) 0x61efe0
(gdb)
怎麼會這樣,調試器不知道它應該是一個const鎮指針,但不能夠訪問內存給我一個轉儲?我很確定這種方法沒有錯誤,因爲它在崩潰之前使用了幾千次,就像程序中的其他函數一樣。有沒有可能這是與操作系統相關的問題?我正在使用Linux Ubuntu 64位。
我的簡化算法:
bool solveproblem(ptr_to_model) {
if(way_one(ptr_to_model))
return true;
if(way_two(ptr_to_model))
return true;
if(check_if_solved)
return true;
return false;
}
bool way_one(ptr_to_model) {
for(go_through_current_problem_configuration) {
if(check_stuff) {
ptr_to_model->execute_partial_solution(...); //adds another problem configuration to the stack within the model
if(solveproblem(ptr_to_model))
return true;
ptr_to_model->redo_last_step();
}
}
return false;
}
bool way_two(...) {
/*basicly the same as way one*/
}
bool check_if_solve(...) {
if(problem_solved)
return true;
else
return false;
}
該模型是類同的名稱,它代表所有通過推動其堆棧上一個新的「層」,其是經修飾的步驟通過時所作的算法(hopfully簡化)問題,考慮到算法評估的部分解決方案。希望我把它縮小到可以理解的程度。
這是一個非常大的遞歸深度!你能給我們簡單的算法代碼嗎?在某些情況下,您可以將遞歸「展開」爲無限循環。 – Blender
這幾乎可以肯定是你的代碼有問題,而不是「操作系統相關的問題」。您可能會耗盡某些資源(例如堆棧空間),或者在代碼中碰到一些特定的案例錯誤。沒有看到代碼是不可能的。 – NPE
我發現通過將assert()放入您的代碼來驗證不變量,調試深度遞歸算法效果最佳。這樣,當你遇到不希望發生的情況時,強迫它轉儲核心,而不是在很晚以後才能獲得SIGSEGV。在這種情況下,斷言也是可取的,因爲你有1700個遞歸調用,你將很難找到一個不會碰到成千上萬次的好斷點。 – Kevin