VB6 中“堆栈空间不足”的可能原因
Posted
技术标签:
【中文标题】VB6 中“堆栈空间不足”的可能原因【英文标题】:Likely cause of "Out of stack space" in VB6 【发布时间】:2012-04-12 19:17:44 【问题描述】:Error 28 - "Out of stack space"
错误的最可能原因是无限或非常深的递归,它占用了太多的堆栈内存吗?
其他可能的原因是什么?
【问题讨论】:
我认为这个问题没有代码是有效的。在这种情况下,如果他知道导致问题的相关代码,那么他就不需要问这个问题。虽然显然一个一般性问题只会出现一般性错误。为了我的两分钱,我想问你是否在调试器中捕获了错误并检查了调用堆栈? @tcarvin:调试器中尚未出现错误。仅限现场。不幸的是(很明显)代码没有适当的错误处理,所以我只有一个运行时错误。 假设你已经很好地描述了重现错误的步骤,但是你不能在你的开发机器上重现它,并且在阅读了相关代码之后没有什么明显的地方。然后,您需要添加一些日志记录和一些错误处理并将新构建发送到站点,以便他们可以重现它,然后发回日志。 @MarkJ:是的,这是一个很好的计划,但如果时间至关重要呢?如果我需要在不将新版本部署到站点的情况下快速找出模块中出现此错误的原因,我应该在代码中寻找什么? @CraigJ Martin 的回答很好。 “事件级联”可能很难发现。有时您有一个事件处理程序会更改控件的无害属性 - 但该属性更改会再次触发事件。 (或者它触发了另一个事件,它改变了一个不同的属性......最终你最终回到了初始属性)。 【参考方案1】:MSDN 中的here 描述了您的错误。
注意:这篇 MSDN 文章与 Visual Studio 2005 相关。但可能会说同样的限制适用于 VB6。
检查过程是否嵌套太深。 确保递归过程正确终止。 如果局部变量需要比可用空间更多的局部变量空间,请尝试在模块级别声明一些变量。您还可以通过在 Property、Sub 或 Function 关键字前加上 Static 来声明过程中的所有变量。或者,您可以使用 Static 语句在过程中声明各个静态变量。 将一些固定长度的字符串重新定义为可变长度的字符串,因为固定长度的字符串比可变长度的字符串使用更多的堆栈空间。您还可以在不需要堆栈空间的模块级别定义字符串。 检查嵌套 DoEvents 函数调用的数量,方法是使用“调用”对话框查看堆栈中哪些过程处于活动状态。 确保您没有通过触发调用堆栈上已存在的事件过程的事件而导致“事件级联”。事件级联类似于未终止的递归过程调用,但不太明显,因为调用是由 Visual Basic 进行的,而不是代码中的显式调用。使用“调用”对话框查看堆栈中哪些过程处于活动状态。[更新]
您可以通过 here 找到 Visual Studio 6 (VB6) 文章。
您有太多活动的 Function、Sub 或 Property 过程调用。 检查过程没有嵌套太深。对于递归过程尤其如此,即调用自身的过程。确保递归过程正确终止。使用“调用”对话框查看哪些过程处于活动状态(在堆栈上)。 您的局部变量需要比可用空间更多的局部变量空间。 尝试在模块级别声明一些变量。您还可以通过在 Property、Sub 或 Function 关键字前加上 Static 来声明过程中的所有变量。或者,您可以使用 Static 语句在过程中声明各个静态变量。 您的固定长度字符串过多。 过程中的固定长度字符串访问速度更快,但比可变长度字符串使用更多的堆栈空间,因为字符串数据本身放在堆栈上。尝试将一些固定长度的字符串重新定义为可变长度的字符串。在过程中声明可变长度字符串时,只有字符串描述符(而不是数据本身)放在堆栈上。您还可以在不需要堆栈空间的模块级别定义字符串。在模块级别声明的变量默认是公共的,因此该字符串对模块中的所有过程都是可见的。 您有太多嵌套的 DoEvents 函数调用。 使用“调用”对话框查看堆栈中哪些过程处于活动状态。 您的代码触发了事件级联。 事件级联是由触发一个调用已经在堆栈上的事件过程的事件引起的。事件级联类似于未终止的递归过程调用,但不太明显,因为调用是由 Visual Basic 进行的,而不是通过代码中的显式调用。使用“调用”对话框查看哪些过程处于活动状态(在堆栈上)。【讨论】:
+1 “事件级联”可能很难被发现。有时您有一个事件处理程序会更改控件的无害属性 - 但该属性更改会再次触发事件。 (或者它触发了另一个事件,它改变了一个不同的属性......最终你最终回到了初始属性)。 如果您可以提供指向等效 VB6 文章的链接,那么我将授予此答案。我认为这只是公平的,因为问题是关于 VB6。【参考方案2】:我有一个案例,而不是:
Public Property Let EmployeeNo(ByVal vdata As String)
mvarEmployeeNo = vdata
End Property
我弄错了:
Public Property Let EmployeeNo(ByVal vdata As String)
EmployeeNo = vdata
End Property
【讨论】:
【参考方案3】:是的,这是最可能的原因。
【讨论】:
有没有人愿意解释反对票?我完全按照要求回答了这个问题。 这真的让我喷了我嘴里的任何东西,是的,我同意。 这并没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。 @JonLin Erm,对不起?正如我当时评论的那样,它准确地回答了所提出的问题。 @Jasonw 什么“谢谢”?这是一个答案。【参考方案4】:我知道这是一个老问题,但我偶然发现这里试图找出我的情况的原因,并发现它是我造成的一些剩余的 debug.print 语句。它们是在表单中的网格的 FormatText 事件中循环生成的,我猜这会占用所有堆栈空间。
【讨论】:
以上是关于VB6 中“堆栈空间不足”的可能原因的主要内容,如果未能解决你的问题,请参考以下文章