天天看點

c語言記憶體申請函數

幾個常用的記憶體配置設定函數

void* malloc(size_t size)

void* calloc(size_t memb,size_t size)

void* realloc(void *p,size_t size)

void* aligned_alloc(siee_t alignment, size_t size)
           

所引發的錯誤

  • 1.初始化錯誤
  • 2.未檢查傳回值
  • 3.對空指針或無效指針解引用
  • 4.引用已釋放的記憶體
  • 5.對同一塊記憶體釋放多次
  • 6.記憶體洩漏
  • 7.零長度配置設定

1.初始化錯誤

使用malloc()函數在堆區申請的記憶體塊,可能是上一個程式的遺留,具有隐私資訊;   由此引發了三個标準


1."不要假定記憶體配置設定函數已經初始化" -(C安全編碼标準)
2."不要引用未初始化記憶體       " -(C安全編碼标準)
3."清除可能重複使用資源中的敏感資訊" -(C安全編碼标準)
           

2.未檢查傳回值

sign* start = malloc(nmuOfRecodrds * sizeof(sign));
sign* point=(sign*)start;
point=start+tempNum-1;

//當malloc申請失敗時傳回null;而後攻擊者可以直接控制tempNum變量實作任意代碼執行


//"檢測和處理記憶體配置設定錯誤"  -(C安全編碼标準)
           

3.空指針或無效指針解引用

無效指針解引用:就是指引用無效值:空指針,
未按照指定對象類型的正确對齊位址,生存周期結束後的對象位址;
           

4.引用已釋放的記憶體

看對象所存儲的記憶體模型是哪裡,還有他的生命周期;
   如:
   當原有的記憶體被釋放,但是記憶體位址被保留到*p中,而後另外一個函數,
   被重新配置設定到與它對齊大小的資料塊,然後*p就可以使用這一塊記憶體。
           

5.對同一塊記憶體釋放多次

int main(void){
    char* a=NULL ;
    char* b=NULL;


    a=(char *)malloc(sizeof(char)*3);
    free(a);
    b=(char *)malloc(sizeof(char)*3);
    free(a);
    //由于程式員的複制原因忘記改變free(b)是以導緻的記憶體二次釋放問題,會抛出異常,但是一般不會産生後果,但是會導緻直接忘記釋放b所指向的記憶體塊,進而導緻記憶體洩漏
    //由于在系統層面上,記憶體管理器對于堆記憶體的管理其實不會清零,而是将标志位置為零。
    return 0;
}
           

6.記憶體洩漏

這個問題是我最早接觸的關于記憶體的問題,簡單來說就是記憶體沒有回收。
  實際上可能引出很多問題,如果攻擊者可以引用記憶體配置設定函數,
  而且還沒有被釋放掉,就可能導緻拒絕服務攻擊。
  還有就是其實堆記憶體是由作業系統管理的,如果main函數結束之後,堆就會清空
  ,就以目前的記憶體來說,這根本就不足以造成很大的影響,
  但是如果記憶體洩漏是發生在一個多次引用的函數中,如dll或者so中,就會造成很大的影響
           

7.零長度配置設定

暫時沒怎麼看懂,但是我了解到零長度數組在struct中的作用,
結束一個帶有零長度數組的結構,以允許該數組根據需要動态調整大小.這非常友善,當我想确定我的struct在運作時而不是編譯時占用的空間量時,
可以節省大量記憶體。c99支援,gcc也支援,但是vs不支援
           

繼續閱讀