C語言深度解剖筆記6之記憶體管理

2021-09-10 04:52:20 字數 1677 閱讀 9911

什麼是野指標

定義指標變數的同時最好初始化為null,用完指標之後也將指標變數的值設定為null。也就是說除了在使用時,別的時間都把指標「栓」到0 位址處。這樣它就老實了。

棧、堆和靜

我們可以簡單的理解為記憶體分為三個部分:靜態區,棧,堆。

堆疊就是棧,

靜態區:儲存自動全域性變數和static 變數(包括static 全域性和區域性變數)。靜態區的內容

在總個程式的生命週期內都存在,由編譯器在編譯的時候分配。

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

堆:由malloc 系列函式或new 操作符分配的記憶體。其生命週期由free 或delete 決定。

在沒有釋放之前一直存在,直到程式結束。其特點是使用靈活,空間比較大,但容易出錯。

常見的記憶體錯誤及對策

1>指標沒有指向一塊合法的記憶體,定義了指標變數,但是沒有為指標分配記憶體,即指標沒有指向一塊合法的記憶體

struct student

stu,*pstu;

intmain()

結構體內部char *name 這成員在定義結構體變數stu 時,只是給name 這個指標變數本身分配了4 個位元組。name 指標並沒有指向乙個合法的位址,這時候其內部存的只是一些亂碼。所以在呼叫strcpy 函式時,會將字串"jimy"往亂碼所指的記憶體上拷貝,而這塊記憶體name 指標根本就無權訪問,導致出錯。解決的辦法是為name 指標malloc 一塊空間。注意是給這個name指標malloc一塊空間。

2>不管什麼時候,我們使用指標之前一定要確保指標是有效的

一般在函式入口處使用assert(null != p)對引數進行校驗。在非引數的地方使用if(null != p)來校驗。但這都有乙個要求,即p 在定義的同時被初始化為null 了。比如上面的例子,即使用if(null != p)校驗也起不了作用,因為name 指標並沒有被初始化為null,其內部是乙個非null 的亂碼。

關於malloc的函式:

malloc 函式的原型:(void *)malloc(int size).

malloc 函式的返回值是乙個void 型別的指標,引數為int 型別資料,即申請分配的記憶體

大小,單位是byte。記憶體分配成功之後,malloc 函式返回這塊記憶體的首位址。你需要乙個指

針來接收這個位址。

但是由於函式的返回值是void *型別的,所以必須強制轉換成你所接收

的型別。也就是說,這塊記憶體將要用來儲存什麼型別的資料。

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

在堆上分配了100 個位元組記憶體,返回這塊記憶體的首位址,把位址強制轉換成char *型別後賦

給char *型別的指標變數p。

但是,每次你都能分配成功嗎?不一定,如果所申請的記憶體塊大於目前堆上剩餘記憶體塊(整塊),則記憶體分配會失敗,函式返回null。注意這裡說的「堆上剩餘記憶體塊」不是所有剩餘記憶體塊之和,因為malloc 函式申請的是連續的一塊記憶體。

既然malloc 函式申請記憶體有不成功的可能,那我們在使用指向這塊記憶體的指標時,必須用if(null != p)語句來驗證記憶體確實分配成功了,與malloc 對應的就是free 函式了,。free 函式就是把這塊記憶體和p 之間的所有關係斬斷。從此p 和那塊記憶體之間再無瓜葛。至於指標變數p 本身儲存的位址並沒有改變,但是它對這個位址處的那塊記憶體卻已經沒有所有權了。

c語言深度解剖筆記

關鍵字 register 這個關鍵字請求編譯器盡可能的將變數存在 cpu內部暫存器中而不是通過記憶體定址訪問以提高效率。注意是盡可能,不是絕對。你想想,乙個 cpu的暫存器也就那麼幾個或幾十個,你要是定義了很多很多 register 變數,它累死也可能不能全部把這些變數放入暫存器吧,輪也可能輪不到你...

C語言深度解剖 筆記4

1最易變的關鍵字 volatile 型別修飾符 用volatile修飾的變數表示可以被某些編譯器未知的因素更改,比如作業系統 硬體或者其他執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的 就不再進行優化,從而可以提供對特殊位址的穩定訪問。比如 volatile關鍵字告訴編譯器某變數是隨時可能...

c語言深度解剖筆記1

2016.8.14 dage 複習內容 c語言深度解剖筆記1 有三大類 算術運算子 關係運算子與邏輯運算子,還有位運算子等,相同優先順序運算子,從左至右依次運算。注意字尾運算優先順序高於字首。因此 i 應解釋為 i 基本表示式 1級 最高 字尾表示式 2極 單目 一元運算 3級 強制型別表示式 4級...