C ++函数任意退出

时间:2011-04-14 22:34:59

标签: c++

我有一个奇怪的问题:

在我的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。

您认为这可能是什么原因?

3 个答案:

答案 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:

调试时也可以关注堆栈内容更改。