C語言再學習23 記憶體管理(一)

2021-09-29 14:56:51 字數 2794 閱讀 4367

野指標是指向未知的,不可控的,隨機的記憶體位址,進而導致程式執行時出錯,甚至系統奔潰(可能去修改作業系統已經使用記憶體裡的內容)。野指標是指向不可使用記憶體的指標。

測試:

void

wild_point

(void

)}

以上程式如果對指標 cp2 不初始化,編譯即報錯(vs2017)。

(1)定義時,把指標賦值為 null(拴住指標);

(2)釋放記憶體判斷指標是否為空,並且重新賦值為 null(用 malloc 申請了記憶體,應該檢查指標值是否為 null,防止使用值為 null 的指標,動態申請 malloc 與 free 成對出現,防止記憶體洩漏)。

2.1 靜態區

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

2.2 棧

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

2.3 堆

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

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

struct stdudent

st_stu,

*pst_stu;

//----------------------

//第一段

void

stu_test

(void

)//-----------------------

//------------------------

//第二段

void

stu_test

(void

)//--------------------------

定義結構體變數 st_stu 的時候,給結構體分配了 8 個位元組的記憶體空間,但是定義的 char *name 沒有指向乙個合法的位址,所以再呼叫 strcpy 往裡寫資料的時候,程式出錯。

不管什麼時候,使用指標的時候一定要保證指標是有效的。

(2)為指標分配的記憶體太小

void

pch_test

(void

)

針對字串,實際大小為:內容 + 『\0』,所以在 *ptr2 申請記憶體的時候,應該加上 1 位元組的 『\0』。但是注意,如果如果通過陣列方式定義乙個字串,那麼 『\0』 是沒有的。

char buff[7]

=;

(3)記憶體分配成功,但是沒有初始化。

未進行初始化的變數,通過除錯我們可以發現其中要麼是亂碼,要麼是不明所以的資料(區域性變數在棧上,這些空間是反覆使用的,上次使用的「髒資料」可能成為下一次使用這塊空間變數的初始化值)。建議變數在定義的時候,同步進行初始化。比如陣列的初始化,可以用如下方式:

int buff[10]

=;memset

(buff,0,

10);

(4)記憶體越界。

記憶體分配成功,已經初始化,但是操作超出了記憶體的邊界。

int a[10]

=;for(

int i =

0; i<=

10; i++

)//i<=10已經超出了陣列a的空間

(5)記憶體洩漏。

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

malloc 專門用來從堆上分配記憶體。malloc 的函式原型為:

(

void*)

malloc

(int size)

;

malloc 的返回值是乙個 void 型別的指標,引數為 int 型別資料,即為申請記憶體的大小,單位是 byte。記憶體分配成功後,malloc 函式返回這塊記憶體的首位址。我們需要乙個指標來接收這個位址,因為函式的返回值為 void * 型別,必須強制轉換成我們需要的型別,也即這塊記憶體將用來儲存什麼型別的資料。例如:

char

*p =

(char*)

malloc

(100

);

這樣將在堆上分配 100 個位元組的記憶體空間,並返回這塊記憶體的首位址,這裡強制轉換成 char* 型別後賦值給 char * 型別的的指標變數 p。同時可知這塊記憶體將用來儲存 char 型別的資料,只能通過指標變數 p 來操作這塊記憶體,對這塊記憶體的訪問是匿名訪問。因為動態分配的記憶體的時候,可能因為堆上沒有連續的記憶體空間而導致分配失敗,函式返回 null,所以使用動態記憶體之前,需用 (null != p) 來檢查記憶體是否分配成功。

釋放記憶體:

free

(p);

free 函式就做了一件事:斬斷指標變數和這塊記憶體的關係。p 本身儲存的位址並沒有改變,但是它對這個位址處的記憶體已經沒有使用權,被釋放的這塊記憶體裡面儲存的值並沒有改變,只是再也無法使用了。

使用 free 之後,指標變數 p 本身儲存的位址並沒有改變,所以在釋放之後,需要把 p 賦值為 null。

C語言再學習之記憶體對齊

昨天看q3的 看到有個 intsaizeof的巨集,著實暈了一陣。一番google後,終於明白,這個巨集的作用是求出變數占用記憶體空間的大小,先看看 intsaizeof的定義吧 define intsizeof n sizeof n sizeof int 1 sizeof int 1 ansi c...

C語言再學習 函式

一 函式概述 1 首先什麼是函式?函式是用於完成特定任務的程式 的自包含單元。2 為什麼使用函式?第 一 函式的使用可以身故重複 的編寫。第 二 函式使得程式更加模組化,有利於程式的閱讀修改和完善。3 main函式原型 int main int argc,char argv,char envp 第乙...

c語言 再學習筆記

簡單的來說 在區域性變數前加上 static 可以延長他的生命週期 由 函式呼叫時 延長至 程式存活週期 在全域性變數前加上static 可以減小它的作用域 由 多檔案可見,減小到單檔案內 可見 局變數的說明之前再加以static 就構成了靜態的全域性變數。全域性變數本身就是靜態儲存方式,靜態全域性...