Oracle® Developer Studio 12.5:代码分析器用户指南

退出打印视图

更新时间: 2016 年 6 月
 
 

静态代码问题

静态代码检查可查找以下类型的错误:

  • ABR:数组越界读

  • ABW:数组越界写

  • DFM:双重释放内存

  • ECV:显式强制类型转换违规

  • FMR:读取释放的内存

  • FMW:写入释放的内存

  • INF:无限空循环

  • MLK:内存泄漏

  • MFR:缺少函数返回值

  • MRC:缺少 malloc 返回值检查

  • NFR:返回未初始化的函数

  • NUL:NULL 指针解除引用,泄漏指针检查

  • RFM:返回释放的内存

  • UMR:读取未初始化的内存。未初始化的内存读取位操作

  • URV:未使用的返回值

  • VES:超出范围的局部变量使用

本节介绍可能的错误原因以及发生错误的代码示例。

数组越界读 (ABR)

可能的原因:试图读取超出数组边界的内存。

示例:

    int a[5];
    . . .
    printf("a[5] = %d\n",a[5]);  // Reading memory beyond array bounds

数组越界写 (ABW)

可能的原因:试图写入超出数组边界的内存。

示例:

    int a [5];
     . . .
     a[5] = 5; // Writing to memory beyond array bounds

双重释放内存 (DFM)

可能的原因:多次使用同一指针调用 free()()。在 C++ 中,多次对同一指针使用 delete 操作符。

示例:

    int *p = (int*) malloc(sizeof(int));
     free(p);
     . . .       // p was not signed a new value between the free statements
     free(p); // Double freeing memory

读取释放的内存 (FMR)

示例:

    int *p = (int*) malloc(sizeof(int));
    free(p);
    . . .  // Nothing assigned to p in between
    int j = *p; // Reading from freed memory 

写入释放的内存 (FMW)

示例:

    int *p = (int*) malloc(sizeof(int));
     free(p);
     . . .        // Nothing assigned to p in between
     *p = 1; // Writing to freed memory 

无限空循环 (INF)

示例:

    int x=0;
    int i=0;
    while (i200) {
      x++; } // Infinite loop 

内存泄漏

可能的原因:分配了内存,但是在退出或终止函数之前未释放。

示例:

    int foo()
    {
     int *p = (int*) malloc(sizeof(int));
     if (x) {
      p = (int *) malloc(5*sizeof(int));  // will cause a leak of the 1st malloc
      }  
    }                                      // The 2nd malloc leaked here

缺少函数返回值 (MFR)

可能的原因:沿某些路径退出时缺少返回值。

示例:

    #include <stdio.h>
    int foo (int a, int b) 
    {
      if (a) 
        { 
           return b; 
        }
    }            // If foo returns here, the return is uninitialized
    int main ( )
    {
        printf("%d\n", foo(0,30));
    }

缺少 malloc 返回值检查 (MRC)

可能的原因:访问 C 中 malloc 或 C++ 中新运算符的返回值时未执行 null 检查。

示例:

    #include <stdlib.h>
    int main()
    {
     int *p3 = (int*) malloc(sizeof(int)); // Missing null-pointer check after malloc.
     *p3 = 0;
    }  

泄漏指针检查器:Null 指针解除引用 (NUL)

可能的原因:访问可能为 null 的指针,或在指针从不为 null 的情况下针对 null 进行冗余检查。

示例:

    #include <stdio.h>
    #include <stdlib.h>
    int gp, ctl;
    int main()
    {
     int *p = gp;
     if (ctl)
      p = 0;
     printf ("%c\n", *p); // May be null pointer dereference
     if (!p)
      *p = 0; // Surely null pointer dereference

    int *p2 = gp;
    *p2 = 0; // Access before checking against NULL. 
    assert (p2!=0);

    int *p3 = gp;
    if (p3) {
      printf ("p3 is not zero.\n");
    }
    *p3 = 0; // Access is not protected by previous check against NULL. 
    }

返回释放的内存 (RFM)

示例:

    #include <stdlib.h>
    int *foo ()
    {
     int *p = (int*) malloc(sizeof(int));
     free(p);
     return p; // Return freed memory is dangerous
    }
    int main()
    {
     int *p = foo();
     *p = 0;
    }

读取未初始化的内存 (UMR)

可能的原因:读取尚未初始化的局部数据或堆数据。

示例:

    #include <stdio.h>
    #include <stdlib.h>
     struct ttt {
        int a: 1;
        int b: 1;
     };

     int main()
     {
       int *p = (int*) malloc(sizeof(int));
       printf("*p = %d\n",*p); // Accessing uninitialized data 

       struct ttt t;
       extern void foo (struct ttt *);

       t.a = 1;
       foo (&t); // Access uninitialized bitfield data "t.b"
     }

未使用的返回值 (URV)

可能的原因:读取尚未初始化的局部数据或堆数据。

示例:

    int foo();
   int main()
   {
      foo(); // Return value is not used.
   }

超出范围的局部变量使用 (VES)

可能的原因:读取尚未初始化的局部数据或堆数据。

示例:

    int main() 
   {
      int *p = (int *)0;
      void bar (int *);
      {
        int a[10];
        p = a;
      } // local variable 'a' leaked out
      bar(p);
    }