C 記憶體問題

2021-08-01 14:54:33 字數 2471 閱讀 7870

在系統開發過程中出現的bug相對而言是比較好解決的,花費在這個上面的除錯代價不是很大,但是在系統整合後的bug往往是難以定位的bug(最好方式是打樁,通過打樁可以初步鎖定出錯的位置,如:進入函式前列印日誌,離開時再次列印日誌)。而這些難以定位的bug基本分為2類:記憶體錯誤和並非問題。

1、記憶體洩露

如果在堆疊上分配的記憶體使用完成後沒有釋放就會造成記憶體洩露。少量的記憶體洩露不至於讓程式崩潰,但是大量的記憶體洩露就會導致記憶體耗盡,後續記憶體分配失敗,從而導致程式崩潰。長時間執行軟體,即使只有一兩處洩露,同樣會導致程式崩潰。所以有當出現記憶體洩露請檢查是否釋放了資源。

2、記憶體越界訪問

記憶體越界訪問有兩種:一種是讀越界,即讀了不屬於自己的資料,如果所讀的記憶體位址是無效的,程式就立即崩潰。如果所讀的記憶體位址是有效的,在讀的時候不會出現問題,但是由於讀到的資料是隨機的,他會產生不可預料的後果,另一種是寫越界,又叫緩衝區溢位。所寫的資料是隨機的,他也會產生不可預料的後果。

記憶體越界訪問造成的後果非常嚴重,是引起程式不穩定的主要原因之一,最主要的是它造成的後果是隨機的,表現出來的症狀和時機也是隨機的,讓bug的現象和本質看似沒有什麼聯絡,這給bug定位帶來了極大的困難。所以在時機開發過程中,對於外部傳入的引數要仔細檢查。

3、野指標

釋放掉的記憶體會被記憶體管理器重新分配。此時野指標指向的記憶體已經被賦予新的意義。對野指標指向的記憶體訪問,無論是有意的還是無意的,都會為此付出巨大代價,因為它造成的後果,如果越界訪問一樣是不可預料的。解決野指標最好的方法:釋放記憶體後立即把對應指標置為空值。

4、訪問空指標

在訪問指標指向的記憶體時,確保指標不是空指標。訪問空指標指向的記憶體,通常會導致程式崩潰,或者不可預料的錯誤。

5、引用未初始化的變數

未初始化變數的內容是隨機的,使用這些資料會造成不可預料的後果,除錯這樣的bug也非常困難。最好的解決辦法:在宣告變數的時候就對它進行初始化。

6、不清楚的指標運算

如:int *p=....;

p+n等價於(size_t)p+n*sizeof(*p);

7、結構體成員順序變化引發的錯誤

8、結構體大小變化引發的錯誤

9、分配釋放不配對

10、返回指向臨時變數的指標

棧裡面的變數時臨時的,當前函式執行完成時,先關的臨時變數和引數都被清除了。不能把指向這些臨時變數的指標返回給呼叫這,這樣的指標執行的資料是隨機的,會給程式造成不可預料的後果。

11、試圖修改常量

如:char *p="1234";

*p='1';

12、誤解傳值和傳引用

13、重名符號

關於重名問題可以參考:c++重定**決方法總結

14、棧溢位

15、誤用sizeof

c++通常是按值傳遞引數,而陣列則是例外,在傳遞陣列引數時,陣列退化為指標(及按引用傳遞),此時用sizeof是無法獲取資料的大小。

16、位元組對齊

位元組對齊主要目的是提高記憶體訪問效率,在某些平台上,就不僅僅是效率問題,如果不對齊得到的資料是錯誤的。大多數情況下編譯器會保值全域性變數和臨時變數按照正確的方式對齊。記憶體管理器會保證動態按照正確的方式對齊。要注意的是:在不同的型別的變數之間轉換時要小心。

位元組對齊也會造成結構體大小的變化,在程式內部用sizeof來取的結構的大小就可以了。若資料要在不同的機器間傳遞時,在通訊協議中要規定對齊的方式,避免對齊方式不一致引發的問題。

關於位元組對齊問題請參考:關於c++記憶體中位元組對齊問題的詳細介紹

17、位元組順序

位元組順序歷來是設計跨平台最頭痛的問題。位元組順序是關於資料在物理記憶體中的布局問題,最常見的位元組順序有兩種:大端模式和小端模式

大端模式:高位位元組資料存放在低位址處,低位位元組資料存放在高位址處。

小端模式:低位位元組資料存放在記憶體低位址處,高位元組位元組資料存放在記憶體高位址處

如:long n=0x11223344

模式第1位元組 第2位元組第3位元組  第4位元組

大端模式0x110x220x330x44 

小端模式0x440x330x220x11

在普通軟體中,位元組順序問題並不引人注目。而在開發與網路通訊和資料交換有關的軟體時,位元組順序就要多注意了。

18、多執行緒共享變數沒有用valotile修飾

valotile作用:告訴編譯器不要把變數優化到暫存器中。在開發多執行緒的程式是,如果這些執行緒共享一些全域性變數,這些全域性變數最好使用valotile修飾。這樣可以避免因為編譯器優化而引起的錯誤。

C 記憶體問題

可怕的記憶體問題,你一不注意,可能會讓你費勁半天,甚至是好幾天 1 申請記憶體不一定申請成功,因此申請記憶體後一定要判斷是否申請成功 如下 int p new int 30 if p cout 2 野指標問題 兩種 何為野指標,即乙個指標指著不合法的地方,或者指著無效的資料 a char p new...

C 記憶體問題

一 記憶體分配方式 1.從靜態儲存區域分配。內存在程式編譯的過程中就已經分配好,這塊內存在程式的整個執行期間都存在。例如 全域性變數和static變數。2.在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時,這些儲存單元會被自動釋放,棧記憶體分配運算內置於處理器的指...

C 記憶體對齊問題

最近在開發客戶端網路連線過程遇到乙個非常奇怪的問題,這個問題卡了兩天多時間,百般嘗試,一籌莫展!一度讓我懷疑人生了 最後突然想到最近使用 pragma pack,設定記憶體對齊。當我取消這個 後,一切都正常了!事件起因與網路資料協議的定義 struct taginfo word為兩個位元組,byte...