我怎样才能捕获递归代码上的 stackoverflow 异常的根源
我有以下递归代码,并且收到堆栈溢出异常。我无法找出根本原因,因为一旦出现异常,我就无法在 Visual Studio 中获得完整的调用堆栈。
这个想法是,组织团队可以合并成更大的“主要”团队。
有没有人发现下面这段代码中的缺陷可能是罪魁祸首?
private Unit GetUnit(Unit organisationalUnit)
{
if (organisationalUnit.IsMainUnit)
{
return organisationalUnit;
}
if (organisationalUnit.Parent == null)
return null;
return GetUnit(organisationalUnit.Parent);
}
I have the following recursive code and i am getting a stackoverflow exception. I can't figure out the root cause because once i get the exception,i dont get the full call stack in Visual studio.
The idea is that there are org teams that roll up into larger "Main" teams.
Does anyone see a flaw on this code below that could be the culprit?
private Unit GetUnit(Unit organisationalUnit)
{
if (organisationalUnit.IsMainUnit)
{
return organisationalUnit;
}
if (organisationalUnit.Parent == null)
return null;
return GetUnit(organisationalUnit.Parent);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
IsMainUnit
和Parent
的 getter 不会调用GetUnit
。IsMainUnit
andParent
don't callGetUnit
.根总是有
Parent == null
吗?尝试检查
?
Does the root always have
Parent == null
?Tried checking
?
你可以尝试这个来更好地调试它。它不会影响您的生产代码。
再想一想...
很可能您在某个地方有循环引用。
您可以尝试传递一组以前访问过的节点并检查您之前是否访问过该节点。
递归的问题在于,您必须确保它会结束,而未经检查的循环引用是一种不会结束的情况。
You could try this to debug it better. It won't affect your production code.
On second thought...
It's mostlikely that you have a circular reference somewhere.
You could try to pass a set of previous visited nodes and check whether or not you've visited this node before.
The thing with recursion is that you have to be sure that it will end and an unchecked circular reference is a situation where it wouldn't end.
有什么理由不将其重新编码为迭代吗?这样,就可以更轻松地对组织树的深度设置硬性限制,以捕获不良(循环)数据。
递归很有趣,尾部优化甚至可以使其变得高效,但在这里,它看起来就像是解决小问题的大锤子。
Is there any reason not to recode it as an iteration? That way, it'd be easier to set a hard limit on the depth of the organizational tree in order to catch bad (cyclic) data.
Recursion is fun, and tail optimizations can even make it efficient, but here it seems a like large hammer for a small problem.
我对视觉工作室了解不多。
但你应该检查是否复发。例如
I don't know much about visual studio.
But you should check for recurrence. e.g.
一种方法是减少堆栈大小,这样它就可以尽早崩溃。
您可以通过在程序开始时浪费帧来实现这一点,即获得如下堆栈跟踪:f_n,f_(n-1),...,f_1,waste,waste,.. .,waste,如(在 C 伪代码中)
int wasted = 1;
浪费(int n,无效(* f)())
{ if (n > 0) 浪费(n - 1,f) else f ();
浪费+=1; }
main () { 浪费(N,mainprime);其中
mainprime 是旧的 main,N 足够大以达到您想要的 f_1。
One way to do that would be to reduce the stack size so it can crash earlier on.
You could do that by wasting frames upon the beginning of the program, i.e. to get a stack trace like: f_n,f_(n-1),...,f_1,waste,waste,...,waste, as in (in C pseudo-code)
int wasted = 1;
waste(int n,void (*f)())
{ if (n > 0) waste(n - 1,f) else f ();
wasted += 1; }
main () { waste(N,mainprime); }
where mainprime is your old main, and N is big enough to reach the f_1 you want.
代码看起来不错,也许单元树中有一些闭环?尝试添加带有organizationalUnit.GetHashCode值的跟踪行,跟踪输出不受限制,可以帮助检测堆栈溢出原因。
The code looks OK, maybe you have some closed cycles in the Unit tree? Try to add trace lines with organisationalUnit.GetHashCode values, trace output is not limited and can help to detect stack overflow reason.
我想你可以通过重写这个来避免递归,
希望有帮助。
编辑:我刚刚意识到,如果你有某种循环依赖,这仍然会失败。
I guess you could avoid recursion by rewriting this along the lines of
I hope that helps.
EDIT: I just realized this would still fail if you have some sort of cyclic dependency.
您的图表中可能有一个循环(请注意,它不是一棵树)。
您可以使用这样的代码来检测它:
You might have a cycle in your graph (see, it's not a tree).
You can use code like this to detect it: