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

xen*_*vil 5 stack-overflow function overflow visual-studio-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个指针。

进入此功能时,代码使用的内存为60,936K,到堆栈溢出时,内存增加到61,940K。大部分的记忆都进入了sInput。这是错误的原因吗?我不这么认为,因为仅传递了它的指针。其次,我不明白为什么dumpOutput要尝试在堆栈上分配1004K内存?

我在这里完全茫然。任何帮助将不胜感激。

提前致谢。

Han*_*ant 5

根据设计,_chkstk()的工作是生成堆栈溢出异常。您可以通过查看生成的机器代码来对其进行诊断。进入该功能后,右键单击编辑窗口,然后单击“转到反汇编”。您应该看到类似以下内容:

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

通过EAX寄存器传递的值很重要,那就是函数需要的堆栈空间量。然后Chkstk通过探查堆栈页面来验证它是否实际可用。如果您看到它反复循环,则代码中的EAX值很高。像我的一样,保证消耗了堆栈的所有字节。和更多。它可以防止这种情况的发生,通常会出现访问冲突异常。但是不能保证,您的代码可能会意外地写入属于(例如)堆的映射页面。这将产生难以置信的错误诊断。Chkstk()可帮助您在沮丧地使大脑崩溃之前找到这些错误。

我只是用这个小的测试功能来做到这一点:

void test()
{
    char kaboom[1024*1024];
}
Run Code Online (Sandbox Code Playgroud)

我们看不到您的变量,但是该异常表明您要么将大型数组作为局部变量,要么将较大的值传递给_alloca()。通过从堆分配该数组来解决。