1 回答

TA貢獻(xiàn)883條經(jīng)驗(yàn) 獲得超454個(gè)贊
不要混淆了“地址”和“地址中的內(nèi)容”,這是兩碼事!
把內(nèi)存當(dāng)作“一連串的房間”的話,“內(nèi)存地址”是房號(hào),而“地址中的內(nèi)容”是房間里的東西。指針類型中存儲(chǔ)的就是地址。
“malloc怎么也初始化地址為0?”
malloc 會(huì)分配一段指定大小的內(nèi)存,但不會(huì)初始化其中的內(nèi)容,或者說其中的值是隨機(jī)的。
第 1 張圖中你用 malloc 分配了 10 個(gè) int 大小的空間,你可以把這段空間當(dāng)作是 int A[10] 數(shù)組。然后你打印了這個(gè)“數(shù)組A”中的 10 個(gè)元素的值。
在你這個(gè)結(jié)果中,碰巧這 10 個(gè)元素的值都是 0。 注意是“地址中的值為 0”,不是“地址為 0”。
還有,不要因?yàn)榭吹蕉际?0 就覺得“malloc 難道也會(huì)將分配的地址中的值初始化為 0???”,這只是碰巧了而已。
第 2 張圖中,你用?calloc 分配了 10 個(gè) int 大小的空間。和 malloc 不同,calloc 會(huì)將其內(nèi)容初始化為 0。
所以這次打印出的內(nèi)容肯定都是 0 。
第 3 張圖,free(A) 并非只釋放 A[0]。 free 釋放的就是 A 指針?biāo)傅?、之前?malloc 所分配到的全部內(nèi)存。重要的一點(diǎn)是:free 一個(gè)指針之后,再訪問該指針的結(jié)果是未定義的!
所以不要再通過 A 測試那些內(nèi)存中的值了,它們可能是任何值。
記?。阂坏?free 了某個(gè)指針,除非再給該指針賦予有意義的新地址,否則不要再按照原值使用該指針了。
第 4 張圖,realloc 會(huì)“重分配”之前分配到的內(nèi)存,同時(shí)調(diào)整內(nèi)存的大小,并且盡可能保留原內(nèi)存中的值。當(dāng)新內(nèi)存大于原內(nèi)存時(shí),多出來的內(nèi)存中的值是未定義的,也就是說多出來的內(nèi)存中的值是隨機(jī)的。
所以你的結(jié)果中,多出來的 135145、0、0、0、0 都是隨機(jī)值。和前面的例子一樣,只不過是碰到 0 比較多而已,并非是“后面初始化為 0”。
另外說一下:其實(shí) realloc 并不保證新內(nèi)存肯定在原內(nèi)存的位置上分配,它只保證新內(nèi)存中保留原內(nèi)存中的值。 在你的這個(gè)例子中,你打印了 A 和 B 的值,你可以看到它們確實(shí)是同一個(gè)地址,也就是說這一次 realloc 確實(shí)是在原內(nèi)存位置上分配新內(nèi)存的。
其實(shí)你不用想這么多。在初學(xué)階段,你只要記住這些函數(shù)的行為,然后按照它們的規(guī)則使用這些函數(shù)即可。尤其是對于那些“未定義行為”,記住永遠(yuǎn)不要寫依賴于“未定義行為”的代碼就好了。 當(dāng)看到了“未定義行為”,初學(xué)時(shí)不用絞盡腦汁想“為什么是這樣的呀??”,因?yàn)?C 語言標(biāo)準(zhǔn)已經(jīng)告訴你了這些行為是未定義的,所以出現(xiàn)什么樣的情況都有可能。
當(dāng)然了,雖說是“未定義行為”,到底還是有一定的原因造成你所看到的結(jié)果的。是的沒錯(cuò),當(dāng)你足夠通曉 C 語言之后,自然會(huì)明白為什么你看到的“未定義行為”表現(xiàn)出這樣或那樣的結(jié)果。 只不過不要在初學(xué)時(shí)(尤其是在沒有人指導(dǎo)時(shí))就想這些,因?yàn)槟愫芸赡軙?huì)加入很多錯(cuò)誤的“腦補(bǔ)”,這反而會(huì)造成你理解錯(cuò)誤(你發(fā)的這個(gè)問題就是如此啊)!
添加回答
舉報(bào)