• Cppcheck代码分析下


    1、流解析

       解析函数中的可能的代码执行流, 函数实际执行中只会执行代码流中的一条流

       分析: 分支语句 if-else ,switch-case

                循环语句 while, do-while ,for

    2、代码流举例

    2.1 示例代码

    int main(int argc,char ** argv)
    {
            std::string p_str= new  std::string() ; 
            if(std::string == NULL)
            {
                return 0;  
            }
          else
            {
                delete p_str;
            }
          return 0;
    }

    2.2 执行代码分析

    2.2.1 执行路径1

    int main()
    {
        string *p_str;
        p_str= new string() ;
    
        (p_str == NULL);
        {
           return 0; 
        }
    }

    2.2.2 执行路径2

    int main()
    {
        string *p_str;
        p_str = new string() ;
    
        (p_str == NULL);
        {
            delete p_str;
        }
        return 0;
    }

    2.2.3 保留条件信息

    #conditon ( )
    
    #conditon_contrary ( )
    
    int main()
    {
        string *p_str;
        p_str= new string() ; 
    
        #conditon (p_str= = NULL);
        {
             return 0; 
        }
    }
    
    
    int main()
    {
       string *p_str;
       p_str= new string() ;
    
       #conditon_contrary (p_str= = NULL);
        {
           delete p_str;
        }
        return 0;
    }

    2.2.4 等价替换—if

      If

    if(condition)
    {
       …
    }

      2 paths

      1->   (condition)
      2->   (condition){ …}

      If else

    if(condition)
    {
       …
    }
    else
    {
       ……
    }

      2 paths

      1->   (condition){ …}
      2->   (condition){ ……}

    2.2.5 等价替换—switch

    swtich( int_condition)
    {
       case 1:
            codes_1   
       case 2:
            codes_2
       default:
            codes_DF
    }

      N paths

      1->  swith (int_condition) { codes_1 codes_2 codes_DF}
      2->  switch (int_condition) { codes_2   codes_DF }
      3->  switch (int_condition) { codes_DF }

    2.2.6 等价替换—while

    while ( condition)
    {
       codes
    }

      2 paths
      1->   (condition) ;loop{  codes ;(condition) ;}
      2->  (condition) ;  //未进入循环语句

    2.2.7 等价替换—do while

    do
    {
       codes
    }
    while ( condition)

      1 path
      1->   loop{  codes ;(condition) ;}

    2.2.8 等价替换—for

    for( initial;condition;iterate)
    
    {
       codes;
    }

      2 path

      1->   initial ; condition ;loop{  codes ; iterate; condition;}
      2->   initial ; condition ;

    3、算法思想

    3.1 嵌套问题

      代码嵌套关系复杂

      解决方案 ->递归算法

    3.2 空间问题

      path多,而且会重复

      解决方案 -> codeblock

    3.3 codeblock

      将连续执行的代码部分以代码块的方式组合。

      多条路径共用重复的代码块

      codePath<-codeBlock<-token

       Codeblock 重用

     

    4、内存泄露检查

      函数内内存泄露检查

      找出所有与内存分配相关的函数

      找出与内存分配地址相关指针(传递性)

      是否地址传递到外部空间

      路径状态判断

      内存泄露特征

      内存申请成功&&代码路径上没有释放空间&&地址没有传递到外部空间

      地址值传递到外部空间方法:

      1.函数参数(指向指针的指针参数)

      2.调用其他函数时当参数

      3.返回值

      4.类成员变量

      5.全局变量

    5、其他检查流程

    5.1 其他解析

      危险使用

      使用指针前没有判断指针的值是否为空

      重复释放

      申请释放函数不一致

      malloc-free 

      new-delete

      new[]-delete[]

      ……

    5.2 内存解析算法

    5.2.1 pointerSet存放分配内存地址的指针

      发生指针传递时加入新集合成员

      指针被重新赋值时从集合中删除

    5.2.2 检查集合中的指针

      1.当做函数的参数使用

      2.当做返回值

      3.赋值给(指向指针的参数)

    5.2.2 路径上的内存状态

      UNSURE     申请内存结果未知

      NULL       申请内存失败

      OK           申请内存成功

      DEALLOCATE   内存被释放

      PASSOUT    内存地址被传递到其他窗口

    5.3 条件判断解析

    5.3.1 解析#condition(……

      OK NULL UNSURE NEVER

      条件语句中常见逻辑符号&& || 及小括号()

      ((ptr>0)&&other&&other)  => OK

      ((ptr>0)&&other||other)  => UNSURE

      ((ptr>0)&&(other||other)) => OK

      从左到右,深度遍历

    5.3.2 条件判断解析算法

      OK NULL UNSURE NEVER

      (any)  &&  UNSURE = any

      (any)   ||   UNSURE = UNSURE

      (any)  &&  NEVER = NEVER

      (any)   || NEVER = any

      OK  &&  NULL = NEVER

      OK  ||  NULL = UNSURE

      ( A && B || C )

      ptr is a pointer in pointerSet

      (ptr)                  OK

      (|ptr)                 NULL

      (0 < ptr) (ptr > 0)        OK

      (0 != ptr) (ptr != 0)       OK

      (0 == ptr )              NULL

       other                 UNSURE

      If(A && B|| C )

  • 相关阅读:
    Swizzle在OC问题排查中的应用
    MacOS中系统提供的音频单元
    Mac catalyst 使用iOS-AudioUnit的音频采集、播放
    删除单向链表中的某一个节点
    C语言的的free和c++的delete的区别
    Mac下使用源码编译安装TensorFlow CPU版本
    ROC曲线与AUC值
    Linux中如何产生core文件?
    更改Linux默认栈空间的大小
    互信息(Mutual Information)
  • 原文地址:https://www.cnblogs.com/ChinaHook/p/4661062.html
Copyright © 2020-2023  润新知