我有一个奇怪的问题:
在我的Win32 C ++应用程序中,我有一个函数,在调用另一个函数后函数返回。
void f()
{
//SECTION 1//
if( interactFrame )
{
psFrame->getWindow()->deactivate();
interactFrame = activeFrame = 0;
logFile << "PS deactive" << endl;
}
//SECTION 2//
}
void Window::deactivate()
{
SetLayeredWindowAttributes( handle_, 0, 0, LWA_ALPHA );
SetFocus( applicationWindow_ );
}
在我调用f()
之后,该函数通过第1节,分支到if语句,完成第1行(psFrame->
...)并在此之后返回而不评估剩余的两行和第2节出了分支。例如,当我调用NULL
变量的方法时,我遇到了这种情况,在这种情况下psFrame
,而不是破坏,只返回。但它是一个合法的变量,它的内容和从getWindow()
返回的指针存在。事实上,我可以追踪到deactivate()
完成,但是下一行的断点从未被击中。
实际上这是在一台计算机上运行的相同代码,而不是在我的笔记本电脑上运行。两者都在运行Win 7。
您认为这可能是什么原因?
答案 0 :(得分:4)
听起来像是某种东西(很可能是deactivate
,或者它所调用的东西)正在弄乱堆栈(例如,覆盖缓冲区的末尾)并弄乱返回地址。不过,这将是一个非常疯狂的猜测。
答案 1 :(得分:2)
鉴于您的描述,它仍然听起来像是你的空引用错误。保护你的代码,看看会发生什么:
if( interactFrame )
{
if (psFrame)
{
if (psFrame->getWindow())
{
psFrame->getWindow()->deactivate();
}
// else log("getWindow == null")
}
// else log("psFrame == null")
interactFrame = activeFrame = 0;
logFile << "PS deactive" << endl;
}
除此之外,我们还需要查看更多代码。
更新:好的 - 你发布了更多的代码,这很奇怪,除非发生一些非常奇怪的事情,比如getWindow()正在超越你的堆栈并且丢弃了返回地址。检查getWindow()中的所有局部变量(尤其是字符串和数组)。
GMan也有一个好处 - 如果psFrame在getWindow中返回指向已删除窗口的指针,那也可能是罪魁祸首(根据内存是否已经重新分配,您可能会看到不同的行为)
答案 2 :(得分:1)
我猜行
psFrame->getWindow()->deactivate();
只是生成一个例外。并且您的函数根本不返回 - 它以异常终止。要确认在调用f()
函数之后设置断点(其中一部分是您发布的代码),如果此断点未命中,则可能是异常(可能无效的内存访问或仅仅是抛出C ++异常)。
堆栈损坏也是可能的,它也可能导致异常(除非您不小心用有效地址覆盖可执行内存的返回地址)。
另请注意,如果psFrame
碰巧为0(或其他无效指针),则getWindow()
以任何方式访问其对象的任何非静态成员时,都会保证异常。你会看到你所描述的行为。同样的情况是当psFrame->getWindow()
返回0(或另一个无效指针)并且deactivate()
访问非静态成员时。
<强> UPD:强>
调试时也可以关注堆栈内容更改。