现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

静态变量的使用及其可能会引发的问题

2012-12-13 12:00 工业·编程 ⁄ 共 1234字 ⁄ 字号 暂无评论

    最近在做一个黑匣子的回放系统,运行时发现第一次回放正常,再次回放时就会出现问题。开始以为是内存泄露,今天上午调试发现原来是一个静态变量在作祟。。。 
    首先,看下static声明的静态变量所具有的属性:内存分配位于静态存储区,只会在进程退出时才释放;当一个局部变量声明为static变量时,在函数多次进入时,变量值只被初始化一次。

       然后,来看看我的问题,有一个Button,第一次点击时启动线程,开始回放。在线程函数中,循环调用了另一个函数A,来读取回放文件。由于回放文件每隔500组数据会有一个时间戳,因此在函数A中定义了一个static的变量,用于计数,每调用一次函数A,计数一次,计满500时清零,跳过时间戳。

    本意是希望在多次进入函数A读取数据时,cnt记录读取的次数是否超过500组,从而决定是否跳过时间戳。因此,第一次回放时,肯定不会有任何问题。但是当停止后,再次回放时,由于cnt为静态变量,此时函数A中的cnt并没有得到初始化,仍然保留上一次的计数值,可能不为0,那么就会导致错误计数,跳过了不是时间戳的数据,因而导致了回放错误。
 
    总结经验,我觉得在函数嵌套调用时,一定要注意子函数的static变量问题,防止出现未初始化的现象。在这里,我将cnt换成了类的成员变量来解决。
 
      另外在回放/停止的切换中,我也用了一个static变量,顺便也提下。如下

static BOOL bResult = TRUE;
if(bResult)  
{   //回放
    //add code...
}
else
{   //停止
    //add code...
}
bResult = !bResult;        //取反

    最后,我做了个测试程序,用于测试上面所述的内容。点击Button,开始打印数据;再次点击时停止;然后再次启动打印。。。m_cnt每次都从0开始打印,而cnt每次都从上一次数据开始打印。
 

void CtestDlg::OnBnClickedTest()
{
    static BOOL bResult = TRUE;
    if(bResult)
    {
        m_cnt = 0;   //在这里每次初始化m_cnt
        SetTimer(1, 1000, NULL);
    }
    else
        KillTimer(1);

    bResult = !bResult;        //取反
}

void CtestDlg::OnTimer(UINT_PTR nIDEvent)
{
    static int cnt = 0;
    CString str;
    UpdateData(TRUE);
    str.Format(_T("cnt = %d, m_cnt = %d ;\r\n"), cnt++, m_cnt++);
    m_strDisp+=str;
    UpdateData(FALSE);

    CDialog::OnTimer(nIDEvent);
}

给我留言

留言无头像?