使用递归算法的SIGSEGV
SIGSEGV with a recursive algorithm
我实现了一个递归算法,它运行了大约1730次递归,然后由于一个神秘的SIGSEGV而崩溃。我尝试了gdb,得到了以下输出:
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 Town指针,但不能访问内存给我一个转储?我很确定这个方法中没有错误,因为它在崩溃之前被使用了几千次,就像程序中的其他函数一样。这有可能是操作系统相关的问题吗?我使用的是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;
}
该模型与名称相似,它表示算法通过将新"层"推到其堆栈上所做的所有步骤,该"层"是由旧问题修改(希望简化)的问题,考虑到算法评估的部分解。
如果你在递归中做了1700层,那么你会溢出堆栈并损坏调用参数,这很容易导致这种类型的崩溃。
如果您使用g++,请尝试添加-fstack-protector-all
,看看它是否有助于您获得更好的诊断。
编辑:另一个指示符是如果你在gdb内的反向跟踪变成循环或没有任何结果:这是一个强指示,堆栈已经损坏。
作为对评论的回应,没有一种可靠的方法来确定某些东西是堆栈溢出还是"更正常"的堆损坏。显然,如果可用,valgrind始终是解决内存错误的可靠选项。您可以在shell中使用ulimit
或(我相信)以编程方式使用setrlimit
来配置堆栈限制。请注意,存在硬性上限,并且通常最好更改递归以减少堆栈滥用,而不是增加堆栈大小。
传递给堆栈的参数有多大?在那个深度,如果你在5千米的高度上有8米的堆叠,你可能会溢出来。这对于堆栈变量来说是相当大的,但是可能的。另一种情况是,您可能会通过写入堆栈中存储的缓冲区(通常是字符串缓冲区)的末尾来破坏堆栈。您在return
中崩溃的事实表明这是一种可能性。
- 需要为 C++ 中的以下问题设计递归算法
- 这种用于查找连续子数组中最大和的递归算法有什么优势吗?
- 运行合并排序递归算法时EXC_BAD_ACCESS错误
- 如何改进搜索二项式系数的递归算法
- 如何转换多次调用自己的递归算法?
- 如何将字符串保存在最长的常见子序列递归算法中
- 编写递归算法以从链表中删除元素.编写递归算法以将元素添加到链表中
- 指针似乎迷失在递归算法中
- 如何从递归算法返回节点
- 从递归算法到迭代算法
- 可传递值影响递归算法的渐近时间复杂性
- 我的递归算法中的问题,用于查找所有最短、唯一的路径
- 带有两个递归调用的递归算法的时间复杂性
- 这种递归算法有什么问题?
- C++递归算法中抛出异常
- 将条件递归算法转换为迭代算法
- 递归算法中的分段错误
- printbinary递归算法
- 迭代等价于递归算法
- 使用递归算法的SIGSEGV