《高質量c++和c編程》7.4 指針參數是如何傳遞內存的一節中寫道
GetMemory( *p, = ( *)malloc(() * Test( *str =); strcpy(str, ); }
無法返回內存,可以用如下方式
GetMemory2( **p, *p = ( *)malloc(() * Test2( *str =&str, ); strcpy(str, << str <<
個人的理解就是,實際上指針傳遞仍然是一種值傳遞,只不過在參數是指針的時候,傳遞的是指針的副本,這樣你在地址上的操作實際就反映到了內存中,舉個例子來說,假設有一個函數
fun( *=
當用調用時fun(q),會產生實參的一個副本設為_p,函數體為副本_p分配了內存,實際上並未改變實參p,這就是GetMemory沒有成功的原因。相反,如果我們有如下函數
fun( **p =
在這個函數中,當發生實參調用的時候,仍然會產生實參的副本,但是注意這裡不是改變副本,而是改變副本指向的內存中的內容,這裡p是一個整形指針,在內存中占四個字節,副本和實參指向同一片內存,所以當你
在以副本為地址的內存內賦值3,實際也就是改變了實參指向的內存中的內容。
總結一下就是:指針傳遞仍然是值傳遞,所以我們在函數體內只有操作*p才會達到我們的指針傳遞要求,而不是操作p,這樣操作只在副本上,實際並不反映到實參指向的內存。
書中另一種方法是:
*GetMemory3( *p = ( *)malloc( Test3( *str == GetMemory3(<< str <<
實際是將堆的特性和return相結合,堆上分配的內存在函數不會釋放,而return實際返回的p的一個副本,但是這裡的副本是一個指針,簡單的說是一個內存地址,而這個地址在函數結束後並沒有釋放,所以,我們可以繼續
使用。如果是普通的局部變量,return返回它的一個副本,隨後局部變量隨著函數的結束而被釋放,這在某些時候會引起麻煩,比如
*GetString( p[] = p; Test4( *str == GetString(); cout<< str <<
至於return似乎還有東西說,一時想不起。。。
事情總有例外,今天小妞找我調試程序,發現了一件很奇特的事情,看代碼
getArray( **s, ( (!<<<< i = (i <= (*)malloc(()*.getline(s[i], ++ **s = ( **)malloc(() * ( i=; i<; i++<<s[i]<<
這個程序可以正確編譯執行。而下面代碼
getArray1( **s, s = *[( (!<<<< i = (i < s[i] = [.getline(s[i], ++ ** ( i=; i<; i++<<s[i]<<
這個代碼確實在運行時出錯
分析了一下,個人認為雖然兩個函數的參數都是char **s,但是一個在main()中先分配,一個直接在getArray中分配,原因就在於此,getarray函數在main函數中先分配了內存,然後傳遞給它,雖然仍然是值傳遞,但是
s的元素是指針,getarray函數中在main函數分配的內存上完成了操作,所以當函數結束時,所有操作仍然保留下來。getarray1函數不同,它是在函數體內完整分配內存,然後施加操作的,相當於都在副本上,所有操作都不會
在函數結束後保留下來。
這是個人的一點理解,如有不對的地方還請指教。