C 筆記 《C語言深度剖析》第五章 記憶體管理

2021-07-07 01:44:16 字數 2249 閱讀 6181

本文為個人讀書筆記,僅供記錄學習過程中遇到的日後需要留意的問題,如有相關版權問題請及時通知作者。

野指標

也稱懸垂指標,指向已經不存在的物件。要杜絕野指標,。定義指標變數的同時就初始化為null,用完指標後也將指標變數的值設定為null。

棧、堆、靜態區

堆疊就是棧,而不是堆。堆是heap,棧是stack

靜態區:儲存自動全域性變數和static變數(包括static全域性和區域性變數)。靜態區的內容在整個程式的生命週期內都存在,由編譯器在編譯的時候分配。

棧:儲存區域性變數。棧上的內容只在函式的範圍內存在,當函式執行結束,這些內容也會自動被銷毀。其特點是效率高,但空間大小有限。

堆:由malloc系列函式或new操作符分配的記憶體。生命週期由free或delete決定,在沒有釋放之前一直存在,直到程式結束。特點是使用靈活,空間比較大,但容易出錯。

常見記憶體錯誤及對策

指標沒有指向一塊合法的記憶體

結構體成員指標未初始化,解決的辦法是malloc一塊空間。

沒有為結構體指標分配足夠的記憶體。

函式的入口校驗:不管什麼時候,我們使用指標之前一定要確保指標是有效的。

一般在函式入口處使用assert(null!=p)對引數進行校驗。在非引數的地方使用if(null!=p)來校驗。都要求p在定義的同時被初始化null了。

assert是乙個巨集,而不是函式,包含在assert.h標頭檔案中。如果其後面括號裡的值為假,則程式終止執行並提示出錯;如果後面括號裡的值為真,則繼續執行後面的**。這個巨集只在debug版本上起作用,而在release版本被編譯器完全優化掉。

為指標非配的記憶體太小

盡量使用sizeof的寫法。會提高**的可移植性。

記憶體非配成功,但並未初始化

在定義乙個乙個變數時,第一件事就是初始化。可以初始化為乙個有效的值或0或null。

memset(a,0,sizeof(a))

的哥引數是要被設定的記憶體的起始位址;第二個引數是要被設定的值,第三個引數是要被設定的記憶體大小單位byte

記憶體越界

for迴圈的迴圈變數一定要使用半開半閉區間,如果不是特殊情況,迴圈變數盡量從0開始。

記憶體洩露

會產生洩露的記憶體就是堆上的記憶體,也就是說由malloc系列函式或new操作符分配的記憶體。如果用完之後沒有及時free或delete,這塊記憶體就無法釋放,直到整個程式終止。

malloc原型: (void*)malloc(int size)

malloc函式的返回值是乙個void型別的指標,引數為int型別資料,即申請分配記憶體的大小,單位是byte。記憶體分配成功之後,malloc函式返回這塊記憶體的首位址。需要乙個指標來接受這個位址。但是由於函式的返回值是void *型別的,所以必須強制轉換成接受的型別。

如:char *p=(char *)malloc(100);

在堆上分配了100個位元組記憶體,返回這塊記憶體的首位址,把位址強制轉換成char*型別後賦給char*型別的指標變數p。同時告訴我們這塊記憶體將用來儲存char型別的資料。也就是說你只能通過指標變數p來操作這塊記憶體。這塊記憶體本身沒有名字,對它的訪問時匿名訪問。

如果申請的記憶體塊大於目前堆上剩餘的記憶體塊(整塊),則記憶體分配會失敗,函式返回null

用mallc函式申請0位元組的記憶體,函式不返回null,而是返回乙個正常的記憶體位址。但是這塊記憶體無法使用。

記憶體釋放

free函式只有乙個引數,就是索要釋放的記憶體塊的首位址。

如:free(p)

free的實際上的作用就是切斷指標變數與記憶體的聯絡。

malloc與free要一一對應。

記憶體釋放之後要把p重新變為null

記憶體已經被釋放,但是繼續通過指標來呼叫

1、free(p)之後繼續通過p來訪問記憶體。解決辦法給p置null

2、函式返回棧記憶體。如在函式內部定義了乙個陣列,卻用return語句返回指向該陣列的指標。

3、記憶體使用太複雜。解決辦法重新設計程式,改善物件之間的呼叫關係。

C語言第五章 C語言函式

十進位制轉換成二進位制 void ttob int n 一,為什麼需要函式 在程式中,我們經常要寫一些相同功能的 這時候c語言提供了函式這一概念,幫助我們把重複的 進行抽取歸類 可以想象成乙個黑盒,我們在使用的時候,只注重其函式的功能 進而形成函式。函式的如能如下 二,什麼是函式 邏輯上 函式是能夠...

C語言第五章 語句

在上章中,我們的資料是通過 來賦予變數的,但這不夠,它不能為變數賦予程式執行時輸入的值,為此我們引入i o語句來完成,5.3 變數的作用域 變數的作用域是指變數的作用範圍,也稱為變數的可見性,很顯然,變數在定放之後,並不是任何乙個地方都可以使用,如定義在語句塊裡的變數在語句塊外就不可以使用了,乙個 ...

深度探索C 物件模型筆記 第五章

inline和define 內聯函式在編譯時展開,而巨集是由預處理器對巨集進行展開 內聯函式會檢查引數型別,巨集定義不檢查函式引數 所以內聯函式更安全。巨集不是函式,而inline函式是函式 巨集在定義時要小心處理巨集引數,可能出現二義性 一般情況是把引數用括弧括起來 const常量有資料型別,而巨...