目錄
- 傳統藝能😎
- 過渡區🤣
- 正片開始👀
- 地址空間👏
- 指標與記憶體關系👏
- 記憶體分配與初始化細節👏
- 記憶體泄漏👏
- Cookie👏
傳統藝能😎
小編是大一菜鳥不贅述,歡迎大佬指點江山(QQ:1319365055)
此前博客點我!點我!請搜索博主 【知曉天空之藍】
喬喬的gitee代碼庫(打灰人 )歡迎訪問,點我!
過渡區🤣
現在是北京時間14:00,期末考試,上午線代,還算順利;天是灰色的今天超冷,聽說成都的家好像下雪了還沒問爸爸媽媽是不是真的,如果是真的希望回家的時候還能看見雪吧,

正片開始👀
地址空間👏

首先我們回味一下之前的老圖,這個圖由于是我手殘加 ppt 即時創作,又因為是C語言入門時講的,內容非常粗糙磕磣,要仔細研究這張圖我們應該將它翻轉90度會更加容易理解更貼近原理:

我們所熟知的,堆疊區資料存盤的地址是從高地址到低地址,堆區資料存盤的地址則是由低到高,而堆區下面可細分為未初始化和已初始化的全域資料區,字符常量區和代碼區,而細心的你可能注意到了我代碼區下面留了一撮空間代表下面還有,但這一撮屬于灰色地帶,目前看作為 “記憶體” ,但本質上不是記憶體,涉及到計算機作業系統原理不贅述,
從記憶體中0x000……0到堆區的地方其實基本上伴隨整個程式的運行一直都存在,我們相對熟悉的就是堆疊區和堆區,堆疊區的我們函式呼叫后臨時變數在堆疊幀中形成,隨著申請與釋放來進行空間管理,
那伴隨整個程式的運行一直都存在的這部分資料,像 static 這類函式修飾的變數,為什么又會被改變生命周期呢?其實在編譯的時候就被編譯進了全域資料區,
指標與記憶體關系👏
void function(char *a)
{
return 1;
}
我們在寫函式時如果內容傳的是指標,如果有好的習慣一般會先去對指標做一下合法性判定,這個判定什么意思,比如我們傳了一個野指標,它會指向記憶體中任何一個位置,我是沒有辦法確認這個隨機位置有無訪問權限,所以要做合法性判定,
但是指標如果有具體的指向,對應的合法性我們是沒辦法驗證的,包括野指標,是不是很疑惑,野指標不是隨機指向,說白了就是亂指,那還沒辦法驗證嗎?是的,沒辦法,很簡單,確認指標具體值的合法性,這不是咱作為用戶可以做到的,這屬于作業系統職責,

這種尷尬的情況我們所謂的合法性判定怎么搞呢?我們所謂的“合法”是落足于應用層面,其實所有的指標在沒有被使用時,我們都應該設定成 NULL,這是一個規范問題,
在函式內部要驗證指標合法性時,本質上就是在驗證指標( !=NULL),可以直接 if 判斷,還有就是很多書中用的一個檢查指標的宏——assert ,一般是在除錯階段使用,assert(name)如果內部條件不滿足非空,就會直接咔嚓掉,中道崩殂沒有后續,但是不好意思,assert只能檢驗是否 NULL,不能檢驗是否為野指標,
記憶體分配與初始化細節👏
之前就想專門提一下幾個和記憶體空間有關聯的函式,現在就放在這里一起總結了吧,
我們為指標分配了記憶體,但是記憶體大小多少會影響實際結果,不夠就會造成越界,
char *p = "hello";
char *q = (char*)malloc(sizeof(char)*strlen(p)+1*sizeof(char));
strcpy(q,p);

p是字串變數,長度為 5 個字符,但實際記憶體占用 6 個字符,不要忘了" \0 ",所以我們做 +1 處理,分配完了記得要初始化,初始化為非必須操作,但建議初始化,這是為了能讓咱編碼盤的明明白白,我們初始化變數時直接 0 或者 NULL,陣列可以 = {0},也可以使用 memset 函式:
memset(a,0,sizeof(a));
它的 3 個引數分別代表起始地址,初始化設置的值以及設定的記憶體大小,單位為位元組,
記憶體泄漏👏
int main()
{
while(1)
{
int *p = malloc(1024);
}
}
這里不做測驗了,這會讓電腦越來越卡,死回圈加申請空間,程式級別的老賴,空間只借不還,以上代碼就生動詮釋了何為記憶體泄漏,
給個C語言之外的問題:程式掛了,已經退出了,那記憶體泄露問題還在嗎?我自己的想法是在的,因為記憶體已經被申請了,退出程式只是終止了空間繼續申請,不影響已產生的空間,但是我錯了,其實在程式退出時,作業系統會強制拿回這部分空間,記憶體泄漏也就不在了,
所以諸位警惕windows的作業系統和殺毒軟體這類常駐行程,幾乎從來不會退出,最怕的就是記憶體泄漏,藍屏安排,卡頓安排;但后端的服務器也是如此,無時無刻提供服務,一但記憶體泄露就會嘿嘿,
Cookie👏
malloc 之后空間要給 free 掉,我們 free(p)目前只知道堆空間的起始地址,并不知道要釋放多少空間,如果 p 是 5 個位元組,那么 free 一定會釋放的比5個位元組多,那么辯證思維,其實申請的空間就一定會比 5 個位元組多,
編譯器是怎么做到正確釋放呢?其實實際 malloc 申請空間的時候,系統就會給的更多,多出來的部分,記錄的就是申請的詳細資訊:空間大小,申請時間等等,free 會確認資訊然后精準 free掉,
這部分多申請的空間叫 cookie,記憶體級的 cookie,就是用來保存這些資訊的,再延伸就是C語言的邊界作業系統了,不贅述,
所以我們在 malloc 時肯定是申請大空間會更好,因為 cookie 的比例會更小,想象一下利息相同時你會借多借少就能體會了,
今天就到這里吧,摸了家人們,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/395118.html
標籤:其他
