我在C#.Net中编写了一个WinForms程序,在密码表单中以编程方式单击按钮.
Form1加载并显示Form2为对话框.
如果DialogResult是DialogResult.OK的其他任何东西,应用程序将关闭.
到目前为止,我有一个按钮单击事件,编码如下:
if (txtpass.Text == "")
{
MessageBox.Show("You need to enter a password", "Password", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
txtpass.Focus();
}
else
{
if (txtpass.Text == "1234")
{
radButton1.DialogResult = DialogResult.OK;
radButton1.PerformClick();
}
else
{
MessageBox.Show("Password Incorrect", "Password", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtpass.Text = "";
txtpass.Focus();
}
}
Run Code Online (Sandbox Code Playgroud)
我用radButton1.PerformClick();,但运行程序给我以下消息:
An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll
Run Code Online (Sandbox Code Playgroud)
我不确定导致此异常的原因是什么.
灵感来自这个问题.
显然在以下代码中:
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
if( GetTickCount() > 1 ) {
char buffer[500 * 1024];
SecureZeroMemory( buffer, sizeof( buffer ) );
} else {
char buffer[700 * 1024];
SecureZeroMemory( buffer, sizeof( buffer ) );
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用Visual C++ 10进行编译时使用默认堆栈大小(1兆字节),并在(/ O2)上进行优化,因为程序试图在堆栈上分配1200千字节而发生堆栈溢出.
上面的代码当然有点夸大以显示问题 - 以相当愚蠢的方式使用大量堆栈.然而在实际场景中,堆栈大小可以更小(例如256千字节),并且可能有更多分支具有更小的对象,这将导致总分配大小足以溢出堆栈.
这是没有意义的.最糟糕的情况是700千字节 - 它将是构建一直具有最大总大小的局部变量集的代码路径.在编译期间检测该路径应该不是问题.
因此编译器会生成一个程序,尝试分配比最坏情况更多的内存.根据这个答案, LLVM也是如此.
这可能是编译器的一个缺陷,或者可能有一些真正的理由这样做.我的意思是也许我只是不明白编译器设计中的某些东西可以解释为什么以这种方式进行分配是必要的.
为什么编译器希望程序在最坏的情况下分配比代码需要更多的内存?
c++ stack-overflow compiler-construction memory-management visual-c++
假设在C++中,你在递归函数上做了太多的递归调用并且出现了堆栈溢出错误.
你会如何以延续传递方式重写它以避免堆栈溢出?
我在C++中描绘这个有点困难.
我正在编写一个评分程序,用于学生正在实施递归排序算法.这意味着几个学生可能会输入损坏的代码,导致堆栈溢出.我想以某种方式捕获在调用学生代码时发生的堆栈溢出,以便我可以从他们的分数中扣除并继续进行其他测试.不幸的是,堆栈溢出似乎没有经过其他异常的标准路径 - try/catch块似乎没有帮助.有没有办法在堆栈溢出发生后将执行返回到我的代码?我已经研究过使用线程来做到这一点,但它似乎回到了无法使用try/catch.
1我试图制作一个无限制因子函数(只是出于好奇.)这适用于大型n(尝试高达100000并且它似乎工作,虽然我无法检查输出值的正确性,因为,它是大!)
(BigInt(1) to n).reduceRight(_*_)
Run Code Online (Sandbox Code Playgroud)
但我担心整个BigInt(1) to n范围可能都在记忆中,而我只是逐个元素地需要它reduceRight.看看Scala的标准库代码看起来BigInt(1) to n实际上是输出整个Range而不是懒惰Stream但我发现Stream.range我可以这样使用(注意n+1,流范围是独占的)
Stream.range[BigInt](BigInt(1), BigInt(n+1)).reduceRight(_*_)
Run Code Online (Sandbox Code Playgroud)
它适用于n=10000(由于某种原因,它需要更长的时间!这让我觉得也许正常的范围实际上也是一个Stream?)但是因为n=100000我得到这个堆栈溢出
java.lang.StackOverflowError
at java.math.BigInteger.add(Unknown Source)
at scala.math.BigInt.$plus(BigInt.scala:161)
at scala.math.Numeric$BigIntIsIntegral$class.plus(Numeric.scala:28)
at scala.math.Numeric$BigIntIsIntegral$.plus(Numeric.scala:40)
at scala.math.Numeric$BigIntIsIntegral$.plus(Numeric.scala:40)
at scala.math.Numeric$Ops.$plus(Numeric.scala:208)
at scala.collection.immutable.Stream$$anonfun$range$1.apply(Stream.scala:695)
at scala.collection.immutable.Stream$$anonfun$range$1.apply(Stream.scala:695)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:634)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:626)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:130)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:131)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:131)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
...
Run Code Online (Sandbox Code Playgroud)
很明显,reduceRight就是这样称呼自己
reduceRight(reduceRight(first, second, op), third, op)...
Run Code Online (Sandbox Code Playgroud)
因此堆栈溢出.我假设它不是尾部调用优化的,因为它首先减少然后在返回值之前运行,因此无法进行优化.那我怎么能解决这个问题呢?我是否应该放弃功能方法并针对自定义命令式代码进行减少?
让我感到非常奇怪的是,虽然使用流几乎相同(BigInt(1) …
我正在使用window.onerror捕获和记录客户端错误.我已经阅读过关于这种方法的各种警告,但我无法找到关于这种特殊情况的任何信息.
出于某种原因,IE9似乎没有捕获堆栈溢出异常.以下示例捕获在Chrome和Firefox中运行时的错误以及在IE9中使用devtools并将浏览器模式设置为IE8或IE7.但是,在IE9模式下运行时,它只捕获'test' is undefined异常,但忽略堆栈溢出异常.
我举了一个简单的例子来证明这一点:
window.onerror = errorHandler;
function errorHandler (msg) {
alert(msg);
}
setTimeout(function () {
test.test = "test";
}, 1000);
setTimeout(function stackoverflow() {
stackoverflow();
}, 2000);
?
Run Code Online (Sandbox Code Playgroud)
这是一个工作示例:http://jsfiddle.net/Mzvbk/1/
任何人都能解释为什么会这样吗?
2012年8月29日更新
我也在Internet Explorer开发人员中心发布了这个问题,但到目前为止它并没有给我太多帮助.
此时,最好的猜测(正如@RyanKinal在他的评论中所建议的)是,由于超出了调用堆栈大小,因此没有空间将调用放在堆栈上的错误处理程序中.
我仍然认为错误处理是与普通堆栈分开处理的,因为它似乎在其他浏览器中(甚至是IE的旧版本),但如果不是这样,那么看到引用会很好,错误报告或某种声明,表明这实际上是IE9的情况.
2012年9月5日更新
正如Ren和Vega在他们的评论中所描述的那样,Firefox 15有时(看似随机)似乎也吞下了这个例外.
javascript stack-overflow error-handling internet-explorer-9
我的Mono应用程序在Mac上崩溃并显示此消息(完整日志):
$ mono --debug bin/Debug/SparkleShare.app/Contents/MonoBundle/SparkleShare.exe
[...]
Stack overflow in unmanaged: IP: 0x26eb76, fault addr: 0xbf808ffc
[...]
Run Code Online (Sandbox Code Playgroud)
"in unmanaged"意味着堆栈溢出不在我的代码中(我只有托管代码),而是在我嵌入的库(SQLite,DotCmis,NewtonSoft.Json)或Mono的代码中.
即使我在调试模式下编译并运行,我得到的只是这两个十六进制.
问题:如何调查此堆栈溢出?任何诡计?
注意:相同的库(具有几乎相同的代码)在Linux和Windows上运行良好.
只是好奇.在回答有关捕获StackOverflowErrors的问题时,有人写道:"当然,在某种情况下,堆栈溢出可能会使应用程序不一致,就像内存耗尽一样".StackOverflowErrors有什么特别之处,它们可能会破坏应用程序状态,比如在出现Bug时抛出NullPointerException?我能想到的一件事是StackOverflowError可能发生在通常永远不会抛出异常(或其他Throwable)的地方(例如一个简单的getter),所以程序可能没有为此做好准备.还有更多恶魔般的问题吗?
我今天遇到了AspectJ编译器的StackOverflow错误,我想我应该在StackOverflow上分享它:-)重现错误我做了一个玩具示例
public abstract class Node<T,Q extends Node<T,Q>> implements WithParent<Q>{
private T content;
//getter and setter for content
}
public aspect WithParentAspect {
private T WithParent<T>.parent;
public T WithParent<T>.getParent() {
return this.parent;
}
public void WithParent<T>.setParent(T parent) {
this.parent=parent;
}
}
public interface WithParent<T> { }
public class StringContentNode extends Node<String, StringContentNode>{
public static void main (String [] args) {
StringContentNode root = new StringContentNode();
StringContentNode leaf = new StringContentNode();
root.setContent("root");
leaf.setContent("leaf");
leaf.setParent(root);
System.out.println(leaf);
System.out.println(leaf.getParent());
}
}
Run Code Online (Sandbox Code Playgroud)
尝试编译此代码会导致以下错误:
java.lang.StackOverflowError
at org.aspectj.weaver.World$TypeMap.put(World.java:1198) …Run Code Online (Sandbox Code Playgroud) 注1:这里的CPS代表“持续通过风格”
我对了解如何挂接到C#异步机制非常感兴趣。基本上,据我了解的C#异步/等待功能,编译器将执行CPS转换,然后将转换后的代码传递给上下文对象,该对象管理各个线程上的任务调度。
您是否认为可以利用该编译器功能来创建功能强大的组合器,同时又保留默认的线程方面?
一个例子就是可以递归和记忆诸如
async MyTask<BigInteger> Fib(int n) // hypothetical example
{
if (n <= 1) return n;
return await Fib(n-1) + await Fib(n-2);
}
Run Code Online (Sandbox Code Playgroud)
我设法做到这一点:
void Fib(int n, Action<BigInteger> Ret, Action<int, Action<BigInteger>> Rec)
{
if (n <= 1) Ret(n);
else Rec(n-1, x => Rec(n-2, y => Ret(x + y)));
}
Run Code Online (Sandbox Code Playgroud)
(不使用异步,非常笨拙...)
或使用monad(While<X> = Either<X, While<X>>)
While<X> Fib(int n) => n <= 1 ?
While.Return((BigInteger) n) :
from x in Fib(n-1)
from y in Fib(n-2) …Run Code Online (Sandbox Code Playgroud) c# stack-overflow combinators continuation-passing async-await
stack-overflow ×10
java ×3
c# ×2
c++ ×2
aspectj ×1
async-await ×1
button ×1
click ×1
combinators ×1
compiler-bug ×1
javascript ×1
mono ×1
monodevelop ×1
monomac ×1
range ×1
recursion ×1
reduce ×1
scala ×1
simulate ×1
stream ×1
unmanaged ×1
visual-c++ ×1