返回指向區域性變數的指標或引用

2021-06-27 03:00:53 字數 2853 閱讀 8728

返回區域性變數沒問題

如果返回區域性變數有問題,函式的意義還有嗎?

全域性變數還用返回嗎?

返回指向區域性變數的指標才有問題

, 函式退棧之後,區域性變數消失, 指標將指向未知區域,所以出現問題。

返回區域性變數的引用也是絕對不可以的

。 引用只是變數的乙個別名,變數本體都不存在了,引用當然也沒有任何意義。

還有,如果是堆空間,可以返回,即在函式中用new

申請的空間,是可以返回的

。但是一般的情況下,好的風格是:

盡量在同乙個作用域內成對使用new   

和delete

,(也即不要返回堆空間),因為如果不是這樣,會是你的函式的介面變的不夠靈活, 試想每個呼叫你的函式的人還需要記得去delete

掉你在函式中

new的堆空間, 否則就會造成記憶體洩露。

返回啥其實都是值拷貝! 指標就是指標值拷貝, 

不會拷貝被指向的內容。

永遠不要從函式中返回區域性自動變數的位址

。如果你真的需要這樣操作。

你可以在函式的參數列中傳入乙個指標變數

。然後將需要寫入的資料寫入到該指標變數指向的位址。由於該指標指向的變數,作用域在函式體 之外。因此不會在函式結束結束時被**。

在c語言中為什麼說絕不能返回函式內區域性變數的位址?

在程式中,只在特定的過程或函式中可以訪問的變數,是相對與全域性變數而言的。

全域性變數也稱為外部變數,是在函式的外部定義的,它的作用域為從變數定義處開始,到本程式檔案的末尾。全域性變數全部存放在靜態儲存區,在程式開始執行時給全域性變數分配儲存區,程式行完畢就釋放。

區域性變數可以和全域性變數重名,但是區域性變數會遮蔽全域性變數。在函式內引用這個變數時,會用到同名的區域性變數,而不會用到全域性變數。

區域性變數的特點是:隨函式呼叫時建立 隨函式結束時析構(銷毀)。

設想,如果返回了乙個區域性變數的指標,而恰好區域性變數偏偏又在函式結束後銷毀,但指標並沒有被銷毀,而是被返回,那也就是說,指標指向的正是乙個被銷毀了的物件。

一般的來說,函式是可以返回區域性變數的。

區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及位址,程式不會出錯。但是如果返回的是區域性變數的位址(指標

)的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被釋放了,這樣指標指向的內容就是不可預料的內容,呼叫就會出錯。準確的來說,函式不能通過返回指向棧記憶體的指標

(注意這裡指的是棧,返回指向堆記憶體的指標是可以的)。

下面以函式返回區域性變數的指標舉幾個典型的例子來說明:

1: view plain

copy to clipboard

1. #include 

2. char *returnstr()   

3.    

7. int main()   

8.   

這個沒有任何問題,因為"hello world!"

是乙個字串常量,存放在唯讀資料段,把該字串常量存放的唯讀資料段的首位址賦值給了指標,所以

returnstr

函式退出時,該該字串常量所在記憶體不會被**,故能夠通過指標順利無誤的訪問。

2: view plain

copy to clipboard

1. #include 

2. char *returnstr()   

3.    

7. int main()   

8.    

"hello world!"是區域性變數存放在棧中。當returnstr函式退出時,棧要清空,區域性變數的記憶體也被清空了,所以這時的函式返回的是乙個已被釋放的記憶體位址,所以有可能列印出來的是亂碼。 

3:view plain

copy to clipboard

1. int func()  

2.                      

7.   

8. int * func()  

9.    

區域性變數也分區域性自動變數和區域性靜態變數,由於a返回的是值,因此返回乙個區域性變數是可以的,無論自動還是靜態,

因為這時候返回的是這個區域性變數的值,但不應該返回指向區域性自動變數的指標,因為函式呼叫結束後該區域性自動變數

被拋棄,這個指標指向乙個不再存在的物件,是無意義的。但可以返回指向區域性靜態變數的指標,因為靜態變數的生存

期從定義起到程式結束。 

view plain

copy to clipboard

1. #include 

2. char *returnstr()   

3.    

7. int main()   

8.    

5: 陣列是不能作為函式的返回值的,原因是編譯器把陣列名認為是區域性變數(陣列)的位址。返回乙個陣列一般用返回指向這個陣列的指標代替,而且這個指標不能指向乙個自動陣列,因為函式結束後自動陣列被拋棄,但可以返回乙個指向靜態區域性陣列的指標,因為靜態儲存期是從物件定義到程式結束的。如下:

view plain

copy to clipboard

1. int* func( void )  

2.    

6:返回指向堆記憶體的指標是可以的

view plain

copy to clipboard

1. char *getmemory3(int num)  

2.   

6. void test3(void)  

7.   

程式在執行的時候用 malloc 

申請任意多少的記憶體

,程式設計師自己負責在何時用 

free

釋放記憶體。動態記憶體的生存期由程式設計師自己決定

,使用非常靈活。

函式返回區域性變數的指標或引用

一般來說,由於在離開函式後區域性變數會被釋放,所以是不允許函式返回指向區域性變數的指標或引用的。我們往往需要遵循如下原則 引用作為返回值,必須遵守以下規則 1 不能返回區域性變數的引用。主要原因是區域性變數會在函式返回後被銷毀,因此被返回的引用就成為了 無所指 的引用,程式會進入未知狀態。2 不能返...

不能返回區域性變數的引用

源之 int add1 int a,int b int add2 int a,int b 請問這兩個函式返回有什麼區別,是乙個返回副本,另乙個直接返回嗎?呼叫函式add2有什麼危險嗎?add1的確返回了乙個副本,如果sum是自定義的類型別,可以很明顯看出拷貝建構函式在返回時被呼叫,對於內建型別沒什麼...

千萬不能返回區域性變數的引用??

c primer第7章函式一節,講到返回時,理解返回引用至關重要的是,千萬不能返回區域性變數的引用 意思是返回程式內部定義的變數時可能會出問題,因為當函式執行完畢後,將釋放分配給區域性物件的儲存空間。此時,對區域性物件的引用就會指向不確定的記憶體。覺得不能理解。比如求階乘時,可以使用迭代函式的方法,...