1 回答

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