【发布时间】:2018-06-19 02:31:12
【问题描述】:
我正在研究一个用 c 编写的模拟问题,我的程序的主要部分是一个递归函数。 当递归深度达到大约 500000 时,似乎发生堆栈溢出。
Q1:我想知道这正常吗?
Q2:一般有多少递归函数调用会导致堆栈溢出?
Q3:在下面的代码中,去掉局部变量neighbor可以防止堆栈溢出吗?
我的代码:
/*
* recursive function to form Wolff Cluster(= WC)
*/
void grow_Wolff_cluster(lattic* l, Wolff* wolff, site *seed){
/*a neighbor of site seed*/
site* neighbor;
/*go through all neighbors of seed*/
for (int i = 0 ; i < neighbors ; ++i) {
neighbor = seed->neighbors[i];
/*add to WC according to the Wolff Algorithm*/
if(neighbor->spin == seed->spin && neighbor->WC == -1 && ((double)rand() / RAND_MAX) < add_probability)
{
wolff->Wolff_cluster[wolff->WC_pos] = neighbor;
wolff->WC_pos++; // the number of sites that is added to WC
neighbor->WC = 1; // for avoiding of multiple addition of site
neighbor->X = 0;
///controller_site_added_to_WC();
/*continue growing Wolff cluster(recursion)*/
grow_Wolff_cluster(l, wolff, neighbor);
}
}
}
【问题讨论】:
-
多少?直到堆栈用完。在 Windows 下,系统可以添加额外的内存,所以......这可能需要很多。在你的情况下,你没有很多局部变量(只有一个指针),所以它只是这个指针和函数框架 - 真的太少了。
-
在CentOs 7上500000次递归调用后出现堆栈溢出是否正常?
-
这看起来 awfully familiar ... 500k 调用就可以了,但这完全取决于你系统的堆栈大小和你在那里推送的内容,看看 here
-
如果您需要超过 100 级的递归,那么递归并不是解决问题的正确方法(不包括大多数体面的编译器会为您转换为迭代的“尾”递归)。
-
Linux 机器上的默认堆栈大小为 8 MiB。如果每次调用需要超过 16 个字节的数据(包括返回地址等),那么在 500,000 次调用深度时会遇到问题(但如果您已经从 499,900 个调用中返回,则不会在 500,000 次调用时遇到问题)。引起麻烦的是递归调用的级别数 - 堆栈溢出 - 而不是调用的总数。
标签: c recursion stack-overflow