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 )

posted @ 2015-07-20 11:58  Memset  阅读(1229)  评论(0编辑  收藏  举报