我想在100 X 100的阵列上做DFS。(数组的表示元素代表图形节点)因此,假设情况最糟,递归函数调用的深度可能会达到10000,而每次调用最多会占用20个字节。那么可行的方法是否有可能发生堆栈溢出?
C / C ++中的最大堆栈大小是多少?
请同时为以下两者指定gcc:
1)Windows上的cygwin
2)Unix
一般限制是什么?
我想在100 X 100的阵列上做DFS。(数组的表示元素代表图形节点)因此,假设情况最糟,递归函数调用的深度可能会达到10000,而每次调用最多会占用20个字节。那么可行的方法是否有可能发生堆栈溢出?
C / C ++中的最大堆栈大小是多少?
请同时为以下两者指定gcc:
1)Windows上的cygwin
2)Unix
一般限制是什么?
Answers:
我认为在Visual Studio中,默认堆栈大小为1 MB,因此,如果递归深度为10,000,则每个堆栈帧最多可以包含约100个字节,这对于DFS算法应该足够了。
包括Visual Studio在内的大多数编译器都允许您指定堆栈大小。在某些(全部)Linux操作系统上,堆栈大小不是可执行文件的一部分,而是操作系统中的环境变量。然后,您可以使用来检查堆栈大小,ulimit -s
然后使用来将其设置为新值ulimit -s 16384
。
这是gcc默认堆栈大小的链接。
没有递归的DFS:
std::stack<Node> dfs;
dfs.push(start);
do {
Node top = dfs.top();
if (top is what we are looking for) {
break;
}
dfs.pop();
for (outgoing nodes from top) {
dfs.push(outgoing node);
}
} while (!dfs.empty())
是的,有可能出现堆栈溢出。C和C ++标准不规定诸如堆栈深度之类的东西,这些通常是环境问题。
大多数像样的开发环境和/或操作系统都可以让您在链接或加载时定制进程的堆栈大小。
您应该指定要使用的操作系统和开发环境,以获得更有针对性的帮助。
例如,在Ubuntu Karmic Koala下,gcc的默认设置为保留2M,并提交4K,但是在链接程序时可以更改。使用--stack
选项ld
来做到这一点。
我只是在工作中用光了堆栈,它是一个数据库,并且正在运行一些线程,基本上以前的开发人员在堆栈上抛出了一个大数组,而且堆栈还是很低。该软件是使用Microsoft Visual Studio 2015编译的。
即使线程用完了堆栈,它也默默地失败并继续运行,但只有在访问堆栈中的数据内容时,它才会堆栈溢出。
我能提供的最佳建议是不要在堆栈上声明数组-尤其是在复杂的应用程序和线程中,而要使用堆。那就是它的目的;)
另外请记住,声明堆栈时它可能不会立即失败,而只会在访问时失败。我的猜测是,编译器“乐观地”在Windows下声明了堆栈,即它将假定已经声明了堆栈并且大小足够大,直到可以使用它为止,然后才发现堆栈不存在。
不同的操作系统可能具有不同的堆栈声明策略。如果您知道这些政策是什么,请发表评论。