2011-11-01 62 views
0

这里我想解决此代码中的堆栈溢出问题。 这里在这段代码中,我调用函数p递归350000次,所以我得到了分段错误 当我删除350000并把300000比它工作正常 这里分段错误来,因为我调用递归调用函数p多次或调用递归函数太深。如何在C程序中删除此分段错误

这不工作,因为我采取if(i != 350000)。 其停在可以是在该范围内300000到327480.我测试10次

CODE:

#include <stdio.h> 

void p(char *, int); 

int main() 
{ 
    char *a = "HI"; 
    int b = 10; 
    p(a, b); 
    printf("\nComplete"); 
    return 0; 

} 
void p(char *a, int b) 
{ 
    static long int i = 0; 

    if (i != 350000) 
    { 
     printf("\n%ld \t at Hi hello", i); 
     i++; 
     p(a, b); 
    } else 
    { 
     return; 
    } 
} 

当我使用的valgrind工具比valgraind报告错误这样

==9236== Stack overflow in thread 1: can't grow stack to 0x7fe801ff8 
==9236== 
==9236== Process terminating with default action of signal 11 (SIGSEGV) 
==9236== Access not within mapped region at address 0x7FE801FF8 
==9236== at 0x4EA012E: [email protected]@GLIBC_2.2.5 (fileops.c:1276) 
==9236== If you believe this happened as a result of a stack 
==9236== overflow in your program's main thread (unlikely but 
==9236== possible), you can try to increase the size of the 
==9236== main thread stack using the --main-stacksize= flag. 
==9236== The main thread stack size used in this run was 8388608. 
==9236== Stack overflow in thread 1: can't grow stack to 0x7fe801ff0 
==9236== 
==9236== Process terminating with default action of signal 11 (SIGSEGV) 
==9236== Access not within mapped region at address 0x7FE801FF0 
==9236== at 0x4A2269F: _vgnU_freeres (vg_preloaded.c:58) 
==9236== If you believe this happened as a result of a stack 
==9236== overflow in your program's main thread (unlikely but 
==9236== possible), you can try to increase the size of the 
==9236== main thread stack using the --main-stacksize= flag. 
==9236== The main thread stack size used in this run was 8388608. 
检查此代码

请帮助我,我真的想要这个问题的解决方案。我不能从我的代码递归调用函数的调用。

回答

3

堆栈是不是一个无限的资源。递归很好地适用于相对快速地减少搜索空间的算法(排序数组的二进制排序,二进制或多向树遍历等)。

如果你发现自己的算法需要递归到三百零一百零三级的水平,你真的应该重新考虑使用递归解决方案。

例如,像:

def addUnsigned (a, b): 
    if a == 0: 
     return b 
    return addUnsigned (a-1, b+1) 

的良好匹配的递归。

如果你真的不能删除递归,那么你需要做valgrind建议的,改变堆栈大小。例如,我的系统上的链接编辑器ld有一个--stack选项,它允许您指定保留的(也可以是已提交的)堆栈大小。

+0

那么我如何知道当前的堆栈大小并以编程方式重置堆栈大小 –

+0

您不需要在程序中执行它,它通常由链接器或加载器完成。严重的是,你需要重新审视你的递归需求。 – paxdiablo

+0

回复我......我该怎么做? –

1

有了这个特殊的例子,如果你把你的编译器的优化级别调高到足够高,它应该执行尾部调用消除,这将解决堆栈溢出问题(例如,gcc 4.4.5在-O2及更高版本中这样做) 。

0

如果您仍想以编程方式控制它,您可以在线程中调用您的函数,并为线程设置堆栈大小(并等待线程完成)。