1.3題目三
函式呼叫臨時變數的相關問題。
找出錯誤,並糾正。
void
getmemory
(char
*p)void
test
(void
)int
main()
可以肯定的是以下兩個錯誤:
1、沒有判斷空間申請是否成功。
2、沒有釋放,會導致記憶體洩漏。
還有呢?
題目一解析:
這裡傳入的是一級指標str,str裡存放的是null的位址。
getmemory函式呼叫後,發生形參例項化,產生臨時變數p,拷貝到了str裡的內容(null的位址)。
p指向開闢的空間的位址0x011089c8,但是函式呼叫結束後,臨時變數p立 馬釋放了,雖然p仍舊指向開闢的空間的位址,但!卻是不合法的,無效的。(參考free) 所以無法把開闢的記憶體的位址賦值給str,而且,開闢的記憶體沒有及時釋放,會產生記憶體洩漏。(沒有釋放前,開闢的記憶體一直存在,子函式getmemory結束也存在,程式結束了才消失)。
證明如上圖:
最後,拷貝「hello world」到str裡,str指向的是null,執行結果變成了將「hello world」寫入null的位置,報錯。
如何把申請成功的空間位址p,傳給str,然後輸出「hello world」呢?答案很簡單,想改變實參的內容,就在傳參的時候,傳實參的位址,而不是實參本身。這裡想改變的是實參str裡的內容,所以傳參時,傳&str(二級指標)就好了。(之前寫過幾個交換函式,建立臨時變數和不建立臨時變數作為參考。)
直接看輸出成功的**和執行結果:
這個題目的錯誤在**?並改正。(據我的老師講,是位元組跳動的筆試題)
char
*getmemory1
(void
)int
main()
1.2.1、p[ ]是在棧上開闢空間的,存放的是「hello world」的字元拷貝,getmemory1執行結束後,p[ ]被棧自動釋放,即使return p;是將p在棧上的位址賦給了str,雖然指向了「hello world」,但是對應的空間p[ ]已經被釋放,再呼叫printf函式時,棧結構發生變化,所以列印出來的是亂碼。
不相信來看驗證!
str在沒執行printf時候,還是指向返回的p所指向的空間的。只不過p所指向的空間已經被棧自動釋放了,所以再執行printf時,會顯示字元無效。
再看下面這道題
char
*getmemory2
(void
)int
main()
1.2.2、這個p雖然也是在棧上開闢的,但是存放的內容卻是字元常量區的位址。return p;getmemory2執行結束後,p被釋放。返回的是p裡面存放的字元常量區「h」的位址,將p變數存放的位址「h」賦給了str,這個空間是沒有被釋放的,所以可以正常輸出「hello world」。
char
*getmemory4
(void
)free
(p);
return p;
}
1.3.1、這個會報錯,形成斷點,因為 當p = 「hello world」; 時,是把字元常量區「h」的位址賦給了p,p本來指向的是開闢的空間的位址,但賦值過後p指向了字元常量區「h」。free的時候,釋放的是字元常量區的空間,釋放了一塊不屬於malloc開闢的空間!形成記憶體洩漏。錯!還是一塊唯讀不可更改的空間!大錯特錯!而且本身開闢的空間還沒有被釋放,錯的離譜!
下一題:
char
*getmemory3
(void)}
free
(p);
return p;
}
1.3.2、這個輸出的是亂碼,free前後的p指向的空間雖然不變,返回p,也是把p存放的位址返回給了str,str指向的是free過後的「hello world「對應的空間。是不確定的,非法的,所以是亂碼。
如果刪掉free,,輸出的就是」hello world「。這裡判定空間開闢成功後進行的使用操作是:解引用式的給p指向的動態記憶體空間賦值,沒有改變p的指向,和getmemory3要區別開。
這裡有關函式呼叫產生臨時變數,無法更改外部變數(指與形參對應的實參)的內容。(根據生命週期和作用域來談)我會寫一篇文章表達自己的理解,這是鏈結。
C語言經典筆試題(二)
21 關鍵字volatile有什麼含意?並給出三個不同的例 子。參 乙個定義為volatile的變數是說這變數可 能會被意想不到地改變,這樣,編譯器就不會去假設 這個變數的值了。精確地說就是,優化器在用到這個 變數時必須每次都小心地重新讀取這個變數的值,而 不是使用儲存在暫存器裡的備份。下面是vol...
經典C 語言筆試題目 1
q1 c和c 中struct有什麼區別?q2 c 中的struct和class有什麼區別?a 從語法上講,class和struct做型別定義時只有兩點區別 一 預設繼承許可權。如果不明確指定,來自class的繼承按照private繼承處理,來自struct的繼承按照public繼承處理 二 成員的預...
經典C 語言筆試題目 3
q1 heap與stack的差別 a heap是堆,stack是棧。stack的空間由作業系統自動分配 釋放,heap上的空間手動分配 釋放。stack空間有限,heap是很大的自由儲存區 c中的malloc函式分配的記憶體空間即在堆上,c 中對應的是new操作符。程式在編譯期對變數和函式分配記憶體...