常見的記憶體錯誤及其對策

2021-06-19 17:23:05 字數 2399 閱讀 5555

1.常見的記憶體錯誤及其對策

*記憶體未分配成功卻使用了它:

在使用記憶體之前檢查指標是否為null。如果指標p是函式的引數,那麼在函式的入口處用assert(p!=null)進行檢查 ;如果使用malloc或者new來申請記憶體,應該用if(p==null)或if(p!=null)進防錯處理。

*無論用何種方式建立陣列,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。

*記憶體分配成並且已經初始化,但操作越過了記憶體的邊界。

*記憶體洩露。動態記憶體的申請與釋放必須配對,申請與釋放的次數一定要想同。

*釋放了記憶體卻繼續使用它(三種情況):

(1)物件呼叫關係過於複雜。應重新設計資料結構,解決物件管理混亂局面

(2)函式注意不要返回指向「棧記憶體」的「指標」或者「引用」,該內存在函式體結束時會被銷毀

(3)使用free或delete釋放了記憶體後,沒有將指標設定為null。導致產生「野指標」。  

2. 指標與陣列的對比

*陣列要麼在靜態儲存區被建立(如全域性陣列),要麼在棧上被建立。陣列名對應著(而不是指向)一塊記憶體,其位址與容量在宣告週期內保持不變,只有陣列的內容可以改變。

2.1修改內容

企圖修改常量字串的內容導致執行錯誤。

2.2內容複製與比較

對陣列進行複製:strcpy();

對陣列進行比較:strcmp();

//指標

intlen=strlen(a);

char*p=(char *)malloc(sizeof(char)*(len+1));

strcpy(p,a);              //不要用p=a,

if(strcmp(p,a)==0)  //不要用if(p==a),那是比較位址

2.3.計算記憶體容量

chara="hello world";     //sizeof(a)的值為12(別忘了'\0')。

voidfunc(char a[100])

2.4指標引數是如何傳遞記憶體的?

如果函式的引數是乙個指標,不要指望用該指標去申請動態記憶體。

voidgetmemory(char *p,int num)

voidtest(void)

test函式的語句getmemory(str,200)並沒有使str獲得期望的記憶體,str依舊是null。

毛病出在getmemory()中。編譯器總是要為函式的每個引數製作臨時副本,指標引數p的副本是_p,編譯器使_p=p。如果函式體內的程式修改了_p的內容,就導致引數p的內容作相應的修改。這就是指標可以用作輸出引數的原因。在上面**中,_p申請了新的記憶體,只是把_p所指的記憶體位址改變了,但是p絲毫未變。所以函式getmemory()並不能輸出任何東西。事實上,每執行一次getmemory()就會洩露一塊記憶體,因為沒有用free釋放記憶體。

果非要用指標引數去申請記憶體,那麼應該改用"指向針針的指標"

voidgetmemory2(char **p,int num)

voidtest2(void)

還可以用函式返回值來傳遞動態記憶體,這種方法更簡單。

char *getmemory3(int num)

voidtest3(void)

用函式返回值傳遞動態記憶體這種方法雖然好用,但是要注意不要用return語句返回指向「棧記憶體"的指標,因為該內存在函式結束時自動消亡。

char*getstring(void)

voidtest4(void)

改為下面的**:

char*getstring2(void)

voidtest5(void)

3. 常見的使用規則

[規則1]用malloc或new申請記憶體之後,因該立即檢查指標值是否為null。防止使用指標值為null的記憶體。

[規則2]不要忘記為陣列和動態記憶體賦初值。防止將未被初始化的記憶體作為右值使用。

[規則3]避免數字或指標的下標越界,特別要當心發生「多1」或者「少1」操作

[規則4]動態記憶體的申請與釋放必須配對,防止記憶體洩漏

[規則5]用free或delete釋放了記憶體之後,立即將指標設定為null,防止「野指標」

4. 記憶體分配方式有三種:

(1) 從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。例如全域性變數,static 變數。

(2) 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。

(3) 從堆上分配,亦稱動態記憶體分配。程式在執行的時候用malloc 或new 申請任意多少的記憶體,程式設計師自己負責在何時用free 或delete 釋放記憶體。動態記憶體的生存期由我們決定,使用非常靈活,但問題也最多。

常見記憶體錯誤及其對策

常見記憶體錯誤及其對策 發生記憶體錯誤是件非常麻煩的事情。編譯器不能自動發現這些錯誤,通常是在程式執行時才能捕捉到。而這些錯誤大多沒有明顯的症狀,時隱時現,增加了改錯的難度。有時使用者怒氣沖沖地把你找來,程式卻沒有發生任何問題,你一走,錯誤又發作了。常見的記憶體錯誤及其對策如下 一 記憶體分配未成功...

常見的記憶體錯誤及其對策

1,常見錯誤及其處理策略 1 記憶體分配未成功,卻使用了它。程式設計新手常犯這種錯誤,因為他們沒有意識到記憶體分配會不成功。常用解決辦法是,在使用記憶體之前檢查指標是否為null。如果指標p是函式的引數,那麼在函式的入口處用assert p null 進行 檢查。如果是用malloc或new來申請記...

常見的記憶體錯誤及其對策

作業系統複習 特點 編譯器不能自動發現這類錯誤,通常是在程式執行時才能捕捉到 時隱時現,無明顯症狀 分類 1 記憶體分配未成功,卻使用了它 起因 沒有意識到記憶體分配會不成功 程式設計新手容易犯 解決對策 在使用記憶體之前,檢查指標是否為空指標 null char p char malloc 100...