我有一个程序,它执行递归调用20亿次,堆栈溢出.我做了更改,然后它仍然需要40K递归调用.所以我需要几个MB堆栈内存.我听说堆栈大小默认为1MB.我尝试在线搜索.有人说在视觉工作室里去了属性 - >链接器.........但我找不到它.
有谁知道如何增加它?另外我想知道我是否可以在我的C#程序中设置它?
PS我使用的是32位winXP和64位win7.
我有这个"学习代码",我为f#中的morris seq编写,它遇到堆栈溢出,我不知道如何避免."morris"返回无限序列的"看见和说出"序列(即{{1},{1,1},{2,1},{1,2,1,1},{1,1,1 ,2,2,1},{3,1,2,2,1,1},...}).
let printList l =
Seq.iter (fun n -> printf "%i" n) l
printfn ""
let rec morris s =
let next str = seq {
let cnt = ref 1 // Stack overflow is below when enumerating
for cur in [|0|] |> Seq.append str |> Seq.windowed 2 do
if cur.[0] <> cur.[1] then
yield!( [!cnt ; cur.[0]] )
cnt := 0
incr cnt
}
seq {
yield s
yield! morris (next s) // tail recursion, no stack …Run Code Online (Sandbox Code Playgroud) 有这个代码:
public class Main {
public static void main(final String[] args) throws Exception {
System.out.print("1");
doAnything();
System.out.println("2");
}
private static void doAnything() {
try {
doAnything();
} catch (final Error e) {
System.out.print("y");
}
}
}
Run Code Online (Sandbox Code Playgroud)
还有输出:
1yyyyyyyy2
Run Code Online (Sandbox Code Playgroud)
为什么它打印"y"八次而不再打印.遇到Java println()时如何调用StackOverflowError?
我决定尝试一些实验,看看我能发现堆栈帧的大小,以及当前执行代码在堆栈中的距离.我们可能会在这里调查两个有趣的问题:
StackOverflowError?这是我能想到的最好的:
public static int levelsDeep() {
try {
throw new SomeKindOfException();
} catch (SomeKindOfException e) {
return e.getStackTrace().length;
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来有点黑客.它生成并捕获异常,然后查看堆栈跟踪的长度.
不幸的是,它似乎也有一个致命的限制,即返回的堆栈跟踪的最大长度为1024.除此之外的任何内容都被削减,因此此方法可以返回的最大值为1024.
题:
有没有更好的方法做到这一点,不是那么hacky并没有这个限制?
对于它的价值,我的猜测是没有:Throwable.getStackTraceDepth()是本机调用,它暗示(但不能证明)它不能用纯Java完成.
我们可以达到的等级数量将由(a)堆栈帧的大小和(b)剩余堆栈量确定.让我们不要担心堆栈框架的大小,只需看看我们达到之前可以达到多少级别StackOverflowError.
这是我执行此操作的代码:
public static int stackLeft() {
try {
return 1+stackLeft();
} catch (StackOverflowError e) {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
它的工作令人钦佩,即使它在堆栈剩余量方面是线性的.但这是非常非常奇怪的部分.在64位Java 7(OpenJDK 1.7.0_65)上,结果完全一致:9,923,在我的机器上(Ubuntu 14.04 64位).但Oracle的Java 8(1.8.0_25)给出了非确定性结果:我的记录深度在18,500到20,700之间.
现在为什么它是非确定性的呢?应该有一个固定的堆栈大小,不是吗?并且所有代码对我来说都是确定性的.
我想知道错误捕获是否奇怪,所以我尝试了这个:
public static long badSum(int n) {
if (n==0)
return 0;
else
return 1+badSum(n-1);
} …Run Code Online (Sandbox Code Playgroud) 我究竟做错了什么?简单的递归几千次调用深度抛出一个StackOverflowError.
如果Clojure递归的限制如此之低,我该如何依赖它?
(defn fact[x]
(if (<= x 1) 1 (* x (fact (- x 1)) )))
user=> (fact 2)
2
user=> (fact 4)
24
user=> (fact 4000)
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud) 例如,当我们调用say,一个递归函数时,连续调用存储在堆栈中.但是,由于错误无效,因此错误是"分段错误"(如GCC所示).
它不应该是'堆栈溢出'吗?那两者之间的基本区别是什么?
顺便说一句,解释比维基百科链接更有帮助(经历过这一点,但没有特定查询的答案).
我写了一个表单的递归函数
foo=function(vars,i=2){
**do something with vars**
if(i==length(vars)){
return(**something**)
}else{
foo(vars,i+1)
}
}
Run Code Online (Sandbox Code Playgroud)
length(vars) 是1500左右.当我执行它时,我得到了错误
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
Error during wrapup: evaluation nested too deeply: infinite recursion / options(expressions=)?
Run Code Online (Sandbox Code Playgroud)
很公平,所以我增加了
options(expressions=10000)
Run Code Online (Sandbox Code Playgroud)
然后它工作.
但是,当我读到的帮助文档options有关expressions=,我只是不明白它在说什么.此外,它表明
...如果你增加它,你可能还想用更大的保护堆启动R; ...
所以有人可以告诉我发生了什么,如果我应该expressions像我一样增加参数,以及我是否应该修改其他内容.
我现在有点卡住了,希望有人可以解决一些问题.我对套接字一般来说比较新,但是已经在javascript中打开和关闭了几年,尽管只有完成手头任务所需的深度.因此,我对javascript堆栈堆和一般套接字的一些概念的理解有些局限.好的情况如下:
我创建了一个应用程序,旨在简单地在几台机器上增加一个计数器.有几个用户可以点击"下一步"按钮,它会立即在所有机器上更新.首次连接时,它会检索当前数字,并在本地将其吐出.
我在这里创建了服务器:
var io = require("socket.io");
var sockets = io.listen(8000);
var currentlyServing=0;
sockets.on("connection", function (socket)
{
console.log("client connected");
socket.emit("receive", currentlyServing);
socket.on("update", function(serving)
{
currentlyServing=serving;
if(currentlyServing>100)
currentlyServing=0;
if(currentlyServing<0)
currentlyServing=99;
socket.broadcast.emit("receive", currentlyServing);
console.log("update received: "+currentlyServing);
});
});
console.log("Server Started");
Run Code Online (Sandbox Code Playgroud)
以下是客户端的相关(我希望)摘录:
var socket = io.connect("http://www.sampledomain.com:8000");
//function to update the page when a new update is received
socket.on("receive", function(receivedServing)
{
document.getElementById('msgs').value=""+String("00" + receivedServing).slice(-2);
document.getElementById('nowServing').value=receivedServing;
});
//this is called in an onClick event in the HTML source
//sends the new number to all …Run Code Online (Sandbox Code Playgroud) 我正在调试一个相当奇怪的堆栈溢出,据说是在堆栈上分配太大的变量引起的,我想澄清以下内容.
假设我有以下功能:
void function()
{
char buffer[1 * 1024];
if( condition ) {
char buffer[1 * 1024];
doSomething( buffer, sizeof( buffer ) );
} else {
char buffer[512 * 1024];
doSomething( buffer, sizeof( buffer ) );
}
}
Run Code Online (Sandbox Code Playgroud)
我理解,它依赖于编译器,也取决于优化器决定什么,但为这些局部变量分配内存的典型策略是什么?
输入功能后是否会立即分配最坏情况(1 + 512千字节)或首先分配1千字节,然后根据条件另外分配1或512千字节?
c++ stack-overflow memory-management local-variables visual-c++
我用C编写了一个应用程序,我试图了解-fno-stack-protector编译时命令的用途是什么.对于我的特定应用程序,如果我在防止缓冲区溢出方面使用此命令,则没有任何区别.
我在网上看到,-fstack-protector和-fno-stack-protector命令分别启用和禁用堆栈粉碎保护器,但如果我自己编译应用程序,如何预先启用保护器?命令的使用是否可能取决于运行应用程序的系统?
stack-overflow ×10
recursion ×3
stack ×3
c ×2
java ×2
.net ×1
buffer ×1
buffered ×1
c++ ×1
callstack ×1
clojure ×1
f# ×1
java-8 ×1
javascript ×1
memory ×1
node.js ×1
protection ×1
r ×1
resize ×1
sequences ×1
sockets ×1
stack-size ×1
visual-c++ ×1