C函数调用中的堆栈溢出-MS Visual C++2010学习版



我用C编写了一个函数,当它被调用时,会立即导致堆栈溢出。

原型:void dumpOutput( Settings *, char **, FILE * );

呼叫线路:dumpOutput( stSettings, sInput, fpOut );

在调用它时,stSettings已经是指向Settings结构的指针,sInput是动态分配的2D阵列,fpOutFILE *。它一直到达呼叫线路,没有任何错误,没有内存泄漏等。

实际的函数相当长,我认为不值得在这里分享,因为代码进入函数时会发生溢出(我认为称为序言部分)

我曾尝试使用伪变量直接从main()调用相同的函数,以检查传递的参数是否有任何问题,但它仍然抛出堆栈溢出条件。

调用函数时,chkstk.asm会产生错误。这个asm文件(根据其中的注释)试图探测堆栈,以检查/分配被调用函数的内存。它只是不断跳到Find next lower page and probe部分,直到发生堆栈溢出。

dumpOutput中的局部变量也不是内存野兽,只有6个整数和2个指针。

代码在进入此函数时使用的内存为60936K,在发生堆栈溢出时增加到61940K。这些内存的大部分进入sInput。这是错误的原因吗?我不这么认为,因为只传递了它的指针。其次,我不明白dumpOutput为什么要在堆栈上分配1004K内存?

我在这里完全不知所措。如有任何帮助,我们将不胜感激。

提前谢谢。

根据设计,生成堆栈溢出异常是_chkstk()的作业。您可以通过查看生成的机器代码来诊断它。进入该功能后,右键单击编辑窗口,然后单击"转到反汇编"。你应该看到类似的东西:

003013B0  push        ebp  
003013B1  mov         ebp,esp 
003013B3  mov         eax,1000D4h                  ; <== here
003013B8  call        @ILT+70(__chkstk) (30104Bh) 

通过EAX寄存器传递的值是重要的值,这是函数所需的堆栈空间量。Chkstk然后通过探测堆栈的页面来验证它实际上是可用的。如果您看到它重复循环,那么代码中EAX的值就会很高。和我的一样,它保证消耗堆栈的所有字节。还有更多。这就是它所保护的,你通常会得到一个访问违规异常。但不能保证,您的代码可能会意外地写入到属于堆的映射页。这将产生一个极其难以诊断的错误。Chkstk()可以帮助你在沮丧时找到这些错误。

我只是用这个小小的测试功能:

void test()
{
    char kaboom[1024*1024];
}

我们看不到您的,但异常表明您要么有一个大数组作为局部变量,要么将一个大值传递给_alloca()。通过从堆中分配该数组来修复此问题。

很可能是堆栈损坏或递归错误,但很难在没有看到任何代码的情况下回答

最新更新