深刻理解C指針chap7

CERT組織
地址空間佈局隨機化(Address Space Layout Randominzation):會把應用程序的數據區域隨機放置在內存中,這些數據區域包括代碼,棧和堆。
數據執行保護(Data Execution Prevention)數組

  • 7.1 指針的聲明和初始化
    • 不恰當的指針聲明
      • 不要有歧義
      • 用類型定義代替宏定義(類型定義容許編譯器檢查做用域範圍)。
      define PINT int*   
      	PINT ptr1,ptr2;
      	```//換成
      typedef int* PINT; PINT ptr1,ptr2;
       
    • 使用指針前未初始化
      在初始化指針以前就使用指針會致使運行時錯誤,稱爲野指針
    • 處理未初始化的指針
      • 老是用NULL來初始化指針
      if(pi == NULL){
      	   // 不該該解引pi
      	}else{
      	   // 能夠使用pi
      	}
      • 用assert函數
        assert(pi != NULL);
      • 用第三方工具
  • 7.2 指針的使用問題
    • 覆寫對象邊界之外的內存就會致使緩衝區溢出。(溢出在應用程序的地址空間內;舉出發生在棧幀的元素上;)
      • 訪問數組元素時沒有檢查索引值
      • 對數組指針作指針算術運算時不夠當心
      • 用gets這樣的函數從標準輸入讀取字符串
      • 誤用strcpy和strcat這樣的函數
    • 7.2.1 測試NULL
    float *vector = malloc(20 * sizeof(float));
    	if(vector == NULL){//malloc分配內存失敗}
    • 錯誤使用解引操做
    • 迷途指針
    • 越過數組邊界訪問內存
    • 錯誤計算數組長度
    • 錯誤使用sizeof操做符
    int buffer[20];
    • 必定要匹配指針類型
    int num = 2147483647;  
    	int *pi = #  
    	short *ps = (short*)pi;  
    	//將一個整數指針賦值給一個短整數指針
    • 有界指針
    • 字符串的安全問題
    • 指針算術運算和結構體
    • 函數指針問題
      • if(getSystemStatus == 0)//把函數的地址與0做比較,而不是調用函數後的返回值與0比較。只用函數名自己時返回的是函數的地址。
      • 若是函數類型和函數指針的類型不一樣,不要把函數賦給函數指針
      int (*fptrCompute)(int,int);  
      	int add(int n1,int n2, int n3){return n1+n2+n3;}  
      	fptrCompute = add;  
      	fptrCompute(2,5);  
      	//試圖只用兩個參數調用add函數,而該函數指望的是三個參數,能編譯,但輸出不肯定。
  • 7.3 內存釋放問題
    • 重複釋放
      避免的方法:釋放指針後老是將其置爲NULL,大部分堆管理器都會忽略後續對空指針的釋放。free(name);name=NULL
    • 消除敏感數據
      • 覆寫敏感數據
      int userID;  
      	char *securityQuestion;
      memset(name,0,sizeof(name));
      	userID = 0;
      	memset(securityQuestion,0,sizeof(securityQuestion));
      • name爲指針,應該在釋放內存以前將其清空
      ...  
      memset(name,0,sizeof(name));
      free(name);```
  • 7.4 使用靜態分析工具
    • GCC編譯器的 -Wall選項能夠啓用編譯器警告。
相關文章
相關標籤/搜索