美文网首页
老生常谈,C语言变量生存周期

老生常谈,C语言变量生存周期

作者: 止愚至善 | 来源:发表于2017-01-11 16:07 被阅读0次
    假设创建线程的接口如下
    /*
    @param[in]:
            char *pThreadName                 线程名称
    
            int nPriority                     优先级
    
            int nStackSize                    线程栈空间
    
            ThreadEntry fnThreadEntry         线程入口函数(函数指针)
    
             void *pAry                       入口函数的参数
    
    @param[out]:
             ThreadHandle                     线程句柄
    */
    ThreadHandle  threadCreate(char *pThreadName, int nPriority, int nStackSize, ThreadEntry fnThreadEntry, void *pAry);
    

    创建线程调用的过程可能如下:

    int init(void)
    
    {
           HANDLE handle = creatHandle();//某个会生成句柄的函数
           ThreadHandle  threadHandle =  threadCreate("myThreadName", 10, 10*1024, fnProcess, (void*)&handle);//创建线程,handle 句柄线程作为入口函数的参数
            // do something
    }
    
    void fnProcess(void *pAry)
    {
             if(!pAry)
             {
                  return;
             }
             HANDLE  hCurHandle= * (HANDLE  *)pAry;
            //do something
    }
    

    发现创建线程时,传入的参数(void)&handle,与入口函数接收到的参数pAry是匹配的;但是强制转换后HANDLE hCurHandle= * (HANDLE *)pAry;得到的hCurHandle不等于传入的handle
    强制转换的前后地址都是对的,但是取值的结果不一样,遇到这个问题,刚开始以为是强制转换导致的,后面才往变量声明周期上考虑,HANDLE handle是一个栈变量,当函数 int init(void)执行完毕,该变量的内存空间会被销毁,因此创建线程时传入的(void*)&handle其实是一个野指针,导致void fnProcess(void *pAry)中得到的地址貌似是对的,实则地址上的内容不合法,也就是获取到不确定的错误句柄hCurHandle

    这个问题比较隐蔽,实则是老生常谈的变量生命周期的问题。
    可以这样处理,创建线程时直接将 handle强转为 (void *)handle传入,线程处理函数接收到参数后直接强转为HANDLE hCurHandle= (HANDLE)pAry,这样得到的handle就是正确的了。

    相关文章

      网友评论

          本文标题:老生常谈,C语言变量生存周期

          本文链接:https://www.haomeiwen.com/subject/khdrbttx.html