程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++用參數返回堆上的空間

c++用參數返回堆上的空間

編輯:C++入門知識

《高質量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函數不同,它是在函數體內完整分配內存,然後施加操作的,相當於都在副本上,所有操作都不會

在函數結束後保留下來。

這是個人的一點理解,如有不對的地方還請指教。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved