Section 1: Pointer Declaration and Initialization
     1.1 Improper Pointer Declaration
     1.2 Failure to Initialise a Pointer Before it is Used
     1.3 Dealing with Uninitialised Pointers
Section 2: Pointer Usage Issues
     2.1 Test for NULL
     2.2 Misuse of the Dereference Operator
     2.3 Dangling Pointers
     2.4 Accessing Memory Outside the Bounds of an Array
     2.5 Calculating the Array Size Incorrectly
     2.6 Misusing the sizeof Operator
     2.7 Always Match Pointer Types
     2.8 Bounded Pointers
     2.9 String Security Issues
     2.10 Pointer Arithmetic and Structures
     2.11 Function Pointer Issues
Section 3: Memory Deallocation Issues
     3.1 Double Free
     3.2 Clearing Sensitive Data
Section 4: Using Static Analysis Tools

Section 1: Pointer Declaration and Initialization



     1.1 Improper Pointer Declaration

      int* ptr1, ptr2; // equivalent to  int* ptr1;  int ptr2;
      Correct approach bill be:  int *ptr1, *ptr2;

     #define PINT int*
     PINT ptr1, ptr2;
    

     1.2 Failure to Initialise a Pointer Before it is Used

     Wild pointer:  Using a pointer before it is initialized can result a run-time error.  e.g.
     int* pi;
     ...
     printf(“%d\n”, *pi);
     

     1.3 Dealing with Uninitialised Pointers
     Three approaches:
     (1) Always initialise a pointer with NULL
     (2) Use the assert function
     (3) Use third-party tools
     
     (1). 
     int* pi = NULL;
     ...
     if (pi == NULL) {
          // pi should not be dereferenced
     } else {
          .. pi can be used
     }
     it’s tedious...
     (2) 
     #include <assert.h>
     ...
     assert(pi != NULL);
     // If the expression is true, then nothing happens. If the expression is false, then the program terminates.

     in debug version: the application will not terminated, it will output: “Assertion failed: pi != NULL” .

Section 2: Pointer Usage Issues

     Buffer overflow can happen by:
     (1) Not checking the index values used when accessing an array’s elements
     (2) Not being careful when performing pointer arithmetic with array pointers;
     (3) Using functions such as gets to read in a string from standard input;
     (4) Using functions such as strcpy and strcat improperly.

     2.1 Test for NULL

     float* vector = malloc(20 * sizeof(float));
     if (vector == NULL) {
          // malloc failed to allocate memory
     } else {
          // Process vector
     }

     2.2 Misuse of the Dereference Operator
     int num;
     int *pi = &num;

     Another seemingly equivalent declaration: 
     int num;
     int* pi;
     *pi = &num; // error
     // We are attempting to assign the address of num not to pi but rather to the memory location specified by the contents of pi.

    The correct sequence follows:
     int num;
     int* pi;
     pi = &num;

     2.3 Dangling Pointers
     
     A dangling pointer occurs when a pointer is freed but still references that memory.  Page 51 for details.
     int* pi = (int*) malloc(sizeof(int));
     *pi = 5;
     printf(“%d\n”, *pi);
     free(pi);

     摇摆指针
     如上例,pi内存地址100(栈中), pi存地址500(堆中)。地址500放数字5。
     free(pi) 释放了地址500的内存块。但pi仍指向f地址500。
     接下来我可以:
     *pi = 10;  // 结果不可预测

     解决办法:
     (1)setting a pointer to NULL after freeing it;
     (2)new free function;
     (3)some system will override data when it is freed (e.g. 0XDEADBEEF, VS use 0xCC , 0xCD or 0xDD);
     (4)using third-part tools

     关于new free function:
     void saferFree(void **pp) {
          if (pp != NULL && *pp != NULL) {
               free(*pp);
               *pp = NULL;
          }
     }

     一般用时:
     #define saferFree(p)  saferFree((void**)&(p))

     int main() {
          int* pi;
          pi = (int*) malloc(sizeof(int));
          *pi = 5;
          printf(“Before: %p\n”, pi);
          saferFree(pi);
          return (EXIT_SUCCESS);
     }
     看page 51, page 71

     2.4 Accessing Memory Outside the Bounds of an Array
     
    
    
     

     2.5 Calculating the Array Size Incorrectly
     
     若Alexand 改为Alexander编译都过不了,c99有验证?

     2.6 Misusing the sizeof Operator
    
     80

     2.7 Always Match Pointer Types

    
     

     2.8 Bounded Pointers
     #define SIZE 32
     char name[SIZE];
     char* p = name;
     if (name != null) {
          if (p >= name && p < name + SIZE) {
               // valid pointer
          } else {
               // invalid pointer
          }
     }


     2.9 String Security Issues

     strcpy_s, scanf_s 等。。。

     2.10 Pointer Arithmetic and Structures



     2.11 Function Pointer Issues



Section 3: Memory Deallocation Issues



     3.1 Double Free



     3.2 Clearing Sensitive Data



Section 4: Using Static Analysis Tools