编程中堆栈溢出和缓冲区溢出有什么不同?
我最近在Python程序员面前发现了一个关于F#的演示文稿,看了之后,我决定自己实现"蚂蚁拼图"的解决方案.
有一只蚂蚁可以在平面网格上走动.蚂蚁可以一次向左,向右,向上或向下移动一个空间.也就是说,从单元格(x,y),蚂蚁可以进入单元格(x + 1,y),(x-1,y),(x,y + 1)和(x,y-1).蚂蚁无法访问x和y坐标的数字之和大于25的点.例如,点(59,79)是不可访问的,因为5 + 9 + 7 + 9 = 30,大于25.问题是:如果从(1000,1000)开始,蚂蚁可以访问多少个点,包括(1000,1000)本身?
$ ocamlopt -unsafe -rectypes -inline 1000 -o puzzle ant.ml
$ time ./puzzle
Points: 148848
real 0m0.143s
user 0m0.127s
sys 0m0.013s
Run Code Online (Sandbox Code Playgroud)
整洁,我的结果与leonardo在D和C++中的实现相同.与leonardo的C++实现相比,OCaml版本的运行速度比C++慢大约2倍.这是好的,因为leonardo使用队列来删除递归.
然后我将代码翻译成F# ......这就是我得到的:
Thanassis@HOME /g/Tmp/ant.fsharp
$ /g/Program\ Files/FSharp-2.0.0.0/bin/fsc.exe ant.fs
Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
Thanassis@HOME /g/Tmp/ant.fsharp
$ ./ant.exe
Process is terminated due to StackOverflowException.
Quit …Run Code Online (Sandbox Code Playgroud) 我正在运行一个我在Eclipse中用Java编写的程序.对于非常大的输入,该程序具有非常深的递归级别.对于较小的输入,程序运行正常但是当给出大输入时,我得到以下错误:
Exception in thread "main" java.lang.StackOverflowError
Run Code Online (Sandbox Code Playgroud)
可以通过增加Java堆栈大小来解决这个问题,如果是这样,我该如何在Eclipse中执行此操作?
更新:
@Jon Skeet
代码以递归方式遍历解析树以构建数据结构.因此,例如,代码将使用解析树中的节点执行一些工作,并在节点的两个子节点上调用自身,将它们的结果组合在一起以给出树的整体结果.
递归的总深度取决于解析树的大小,但当递归调用的数量达到1000时,代码似乎失败(没有更大的堆栈).
此外,我很确定代码没有失败,因为它适用于小输入的bug.
我知道无法捕获.NET中的StackOverflowExceptions,删除它们的进程,并且没有堆栈跟踪.这在MSDN上正式记录.但是,我想知道这种行为背后的技术(或其他)原因是什么.所有MSDN都说:
在.NET Framework的早期版本中,您的应用程序可以捕获StackOverflowException对象(例如,从无限递归中恢复).但是,目前不鼓励这种做法,因为需要大量额外的代码来可靠地捕获堆栈溢出异常并继续执行程序.
什么是"重要的附加代码"?这种行为还有其他记录的原因吗?即使我们无法捕获SOE,为什么我们至少不能获得堆栈跟踪?几个同事和我只是沉没几个小时来调试生产StackOverflowException,这可能需要几分钟的堆栈跟踪,所以我想知道我是否有充分的理由让我受苦.
请考虑以下代码.
public class Action {
private static int i=1;
public static void main(String[] args) {
try{
System.out.println(i);
i++;
main(args);
}catch (StackOverflowError e){
System.out.println(i);
i++;
main(args);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了4338正确的价值.捕获StackOverflowError输出后如下连线.
4336
4337
4338 // up to this point out put can understand
433943394339 // 4339 repeating thrice
434043404340
4341
434243424342
434343434343
4344
4345
434643464346
434743474347
4348
434943494349
435043504350
Run Code Online (Sandbox Code Playgroud)
在这里考虑现场演示.它正常工作i=4330.其实这是怎么发生的?
供参考:
我做了以下代码来实现这里发生的事情.
public class Action {
private static int i = 1;
private static …Run Code Online (Sandbox Code Playgroud) 为了估计最大调用深度,递归方法可以用给定量的存储器实现,在堆栈溢出错误可能发生之前计算所用存储器的(近似)公式是什么?
许多人回答"它依赖",这是合理的,所以让我们通过使用一个微不足道但具体的例子来删除一些变量:
public static int sumOneToN(int n) {
return n < 2 ? 1 : n + sumOneToN(n - 1);
}
Run Code Online (Sandbox Code Playgroud)
很容易证明,在我的Eclipse IDE中运行它会爆炸n不到1000(对我来说非常低).这个调用深度限制是否可以在不执行的情况下估算?
编辑:我不禁认为Eclipse有一个固定的最大调用深度1000,因为我得到了998,但是有一个用于main,一个用于初始调用方法,1000总而言之.这是一个"太圆"的数字恕我直言,是一个巧合.我会进一步调查.我只是Dux开销-Xss vm参数; 它是最大的堆栈大小,所以Eclipse运行器必须-Xss1000设置在某处
我在C#中有这两个代码块:
class Program
{
static Stack<int> S = new Stack<int>();
static int Foo(int n) {
if (n == 0)
return 0;
S.Push(0);
S.Push(1);
...
S.Push(999);
return Foo( n-1 );
}
}
Run Code Online (Sandbox Code Playgroud)
class Program
{
static Stack S = new Stack();
static int Foo(int n) {
if (n == 0)
return 0;
S.Push(0);
S.Push(1);
...
S.Push(999);
return Foo( n-1 );
}
}
Run Code Online (Sandbox Code Playgroud)
他们都这样做:
创建一个堆栈(<int>第一个示例为通用,第二个示例为对象堆栈).
声明一个递归调用n次(n> = 0)的方法,并在每个步骤中在创建的堆栈内推送1000个整数.
当我运行第一个例子时Foo(30000)没有发生异常,但是第二个例子崩溃了Foo(1000),只有n = 1000.
当我看到为两种情况生成的CIL时,唯一的区别是每次推送的拳击部分: …
问题
我有一个ASP.NET 4.0应用程序崩溃与一台计算机上的堆栈溢出,而不是另一台计算机.它在我的开发环境中运行良好.当我将站点移动到生产服务器时,它会抛出堆栈溢出异常(在事件日志中看到)并且w3wp.exe工作进程死亡并被另一个进程替换.
我到目前为止所尝试的内容
为了参考,我使用调试诊断工具来尝试确定导致溢出的代码片段,但我不确定如何解释它的输出.输出如下.
ASP.NET网站如何在一台计算机上导致堆栈溢出而在另一台计算机上导致堆栈溢出?
有经验的领导表示赞赏.我将把结果解决方案发布到导致我的答案之下.
调试输出
应用程序:w3wp.exe Framework版本:v4.0.30319描述:由于堆栈溢出,进程终止.
In w3wp__PID__5112__Date__02_18_2011__Time_09_07_31PM__671__First Chance Stack Overflow.dmp the assembly instruction at nlssorting!SortGetSortKey+25 in C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\nlssorting.dll from Microsoft Corporation has caused a stack overflow exception (0xC00000FD) when trying to write to memory location 0x01d12fc0 on thread 16
Please follow up with the vendor Microsoft Corporation for C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\nlssorting.dll
Information:DebugDiag determined that this dump file (w3wp__PID__5112__Date__02_18_2011__Time_09_07_31PM__671__First Chance Stack Overflow.dmp) is a crash dump and did not perform any hang analysis. If you wish to enable combined …Run Code Online (Sandbox Code Playgroud) 这与Node中读取RangeError的错误消息的其他问题不同:超出了最大调用堆栈大小我知道为什么我收到此错误消息.它正在发生,因为我正在递归,事实上已经发生了相当大的反复.
谢谢.
我们可以发现hashcode的list是本身含有的element?
我知道这是一个不好的做法,但这是面试官问的。
当我运行以下代码时,它会抛出一个StackOverflowError:
public class Main {
public static void main(String args[]) {
ArrayList<ArrayList> a = new ArrayList();
a.add(a);
a.hashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有两个问题:
StackOverflowError?