首先來解釋malloc(0)的問題,這個語法是對的,而且確實也分配了內存,但是內存空間是0,就是說返回給你的指針是不能用的,感覺奇怪吧?但是從操作系統的原理來解釋就不奇怪了,這要涉及操作系統維護內存的方法來說了,在內存管理中,內存被分為2部分,棧和堆,棧有自己的機器指令,是一個先進后出的數據結構,我就在這里不再過多解釋了,malloc分配的內存是堆內存,由于堆沒有自己的機器指令,所以要有系統自己編寫算法來管理這片內存,通常的做法是用鏈表,在每片被分配的內存前加個表頭,里面存儲了被分配內存的起始地址和大小,你的malloc返回的就是表頭里的起始指針,這個地址是由一系列的算法得來了,通常不會為0,一旦分配成功,就返回一個有效的指針,對于分配0空間來說,算法已經算出可用內存的起始地址,但是你占用0空間,所以對那個指針操作就是錯誤的,操作系統一般不知道其終止地址,因為有占用大小就可以推出終止地址,還有就是即使分配0空間也要釋放它,其實是釋放的鏈表結點還有,返回的指針是可用地址的起始地址,雖然你可以無限賦值,但是其實是錯誤的,因為可能有其他有用的數據在那一片區域,如果指針越界就會出現意想不到的事情,不懂的再問 |
C規定,未初始化變量的初值為0,這個清0的操作是由啟動代碼完成的,還有已初始化變量的初值的設置,也是由啟動代碼完成的。為了啟動代碼的簡單化,編譯鏈接器會把已初始化的變量放在同一個段:.data,這個段的映像(包含了各個變量的初值)保存在“只讀數據段”,這樣啟動代碼就可以簡單地復制這個映像到 .data 段,所有的已初始化變量就都初始化了。而未初始化變量也放在同一個段:.bss,啟動代碼簡單地調用 memset 就可以把所有未初始化變量都清0。頭疼的野指針
初始野指針(1)野指針通常是因為指針變量中保存的值不是一個合法的內存地址而造成的(2)野指針不是NULL指針,是指向不可用內存的指針(3)NULL指針不容易用錯,因為NULL語句和好判斷一個指針是不是NULLC語言沒有任何手段可以判斷一個指針是否是野指針野指針的由來(1)局部指針變量沒有被初始化(2)使用已經釋放過后的指針
(3)指針所指向的變量在指針之前被銷毀
經典錯誤,你犯了嗎?非法內存操作分析(1)結構體成員指針未初始化(2)沒有為結構體指針分配足夠的內存
d1中的p是野指針,p沒有分配動態內存空間,p指向的是隨機的d2中的p是分配呢5個int,但是分配10個,這種bug很難查內存初始化分析(1)內存分配成功,但未被初始化
內存越界分析(1)數組越界
內存泄漏分析
設計程序最好要單入口單出口多次釋放指針
誰申請誰釋放使用已經釋放的指針
交通規則,還是應該遵守C語言中的交通規則(1)用malloc申請了內存之后,應該立即檢查指針值是否為NULL,防止使用值為NULL的指針
(2)牢記數組長度,防止數組越界操作,考慮使用柔性數組
(3)動態申請操作必須和釋放操作匹配,防止內存泄漏和多次釋放
(4)free指針之后必須立即賦值為NULL
新聞熱點
疑難解答