Static code checking finds the following types of errors:
This section describes possible causes of the error and a code example of when the error might occur.
Possible causes: Attempting to read memory beyond the array bounds.
Example:
int a[5]; . . . printf("a[5] = %d\n",a[5]); // Reading memory beyond array bounds
Possible causes: Attempting to write memory beyond the array bounds.
Example:
int a [5]; . . . a[5] = 5; // Writing to memory beyond array bounds
Possible Causes: Calling free()() more than once with the same pointer. In C++, using the delete operator more than once on the same pointer.
Example:
int *p = (int*) malloc(sizeof(int)); free(p); . . . // p was not signed a new value between the free statements free(p); // Double freeing memory
Possible Causes: The explicit type cast might violate aliasing rules at alias level higher than "any".
Example:
#include<stdio.h> int i =2; int *pi =&i; short *ps; int foo() { ps=(short*)pi; // type cast violation *ps=1; return (*pi); } void main() { printf("%d",foo()); }
Example:
int *p = (int*) malloc(sizeof(int)); free(p); . . . // Nothing assigned to p in between printf("p = 0x%h\n", *p); // Reading from freed memory
Example:
int *p = (int*) malloc(sizeof(int)); free(p); . . . // Nothing assigned to p in between *p = 1; // Writing to freed memory
Example:
int x=0; int i=0; while (i200) { x++; } // Infinite loop
Possible causes: Memory is allocated but not freed before exit or escaping from the function.
Example:
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
Possible causes: Missing return values along some paths to exit.
Example:
#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)); }
Possible causes: Accessing a return value from malloc in C or a new operator in C++ without checking against null.
Example:
#include <stdlib.h> int main() { int *p3 = (int*) malloc(sizeof(int)); // Missing null-pointer check after malloc. *p3 = 0; }
Possible causes: Code is returning an uninitialized value.
Example:
foo() <nfr.c : 7> 4: int foo() 5: { 6: int i; 7:=> return i; 8: }
Possible causes: Accessing a pointer that might equal to null, or redundant checking against null in case the pointer is never null.
Example:
#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. }
Example:
#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; }
Possible causes: Reading local or heap data that has not been initialized.
Example:
#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" }
Possible causes: Reading local or heap data that has not been initialized.
Example:
int foo(); int main() { foo(); // Return value is not used. }
Possible causes: Reading local or heap data that has not been initialized.
Example:
int main() { int *p = (int *)0; void bar (int *); { int a[10]; p = a; } // local variable 'a' leaked out bar(p); }