函式返回區域性變數

2021-08-04 04:40:47 字數 2899 閱讀 3851

函式返回區域性變數

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

區域性變數的作用域

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

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

1. 返回區域性變數的值

可以有兩種情況:返回區域性自動變數和區域性靜態變數,比如,

int func()

區域性變數temp儲存在棧中,函式返回時會自動複製乙份temp的copy給呼叫者,沒有問題。

int func()

區域性變數a儲存在靜態(全域性)儲存區中,從初始化後一直有效直到程式結束,僅分配一次記憶體,並且函式返回後,變數不會銷毀,沒有問題。

vectorfunc()

返回的是v的值拷貝,沒有問題。

person func()

?

返回的也是值拷貝,會呼叫person類的拷貝建構函式,沒有問題。

2. 返回區域性變數的指標

int* func()

?

前面討論過,區域性變數temp儲存在棧中,函式返回時將已銷毀變數的位址返回給呼叫者,結果將是不可預知的。

int* func()

?

區域性變數temp儲存在靜態儲存區,返回指向靜態儲存區變數的指標是可行的。

char* func()

?

對於字串的特殊情況,由於字串test儲存在常量儲存區(不是靜態儲存區),因此函式返回乙個指向常量的字串指標是可行的。

char* func()

?

這種情況下,str被初始化為字串區域性變數,因此函式返回乙個已銷毀的區域性變數是不可行的。解決辦法就是將字串str宣告為static。

char* func()

?

這種情況下,函式返回乙個指向堆記憶體的指標,由於堆儲存區由程式設計師手動管理,因此這種做法是可行的,但是要防止出現記憶體洩露,函式呼叫完後需要手動釋放記憶體。這裡的sizeof作用於指標返回的是指標型別的長度1byte,而如果作用於陣列返回的則是陣列的長度。

char *temp = null;

temp = func();

// some operation...

free(temp);

?3. 返回區域性變數的引用

int& func()

由引用的概念可知,函式返回的是temp本身,而temp在函式返回後已銷毀,結果將是不可預知的。

補充:靜態全域性變數和全域性變數的區別

靜態全域性變數只在當前檔案中可用,全域性變數在其他檔案中也可用,需要用extern宣告。

全域性變數和靜態變數如果沒有手動初始化,則預設由編譯器初始化為0。1:

[cpp]

view plain

copy

#include 

char

*returnstr()   

intmain()     

這個沒有任何問題,因為"hello world!"是乙個字串常量,存放在唯讀資料段,把該字串常量存放的唯讀資料段

的首位址賦值給了指標,所以returnstr函式退出時,該該字串常量所在記憶體不會被**,故能夠通過指標順利無誤的訪問。

2:[html]

view plain

copy

#include 

<

stdio.h

>

char *returnstr()   

int main()   

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

[html]

view plain

copy

int func()  

int * func()  

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

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

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

期從定義起到程式結束。

4:如果函式的返回值非要是乙個區域性變數的位址,那麼該區域性變數一定要申明為static型別。如下:

[html]

view plain

copy

#include 

<

stdio.h

>

char *returnstr()   

int main()   

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

如下:[html]

view plain

copy

int* func( void )  

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

[html]

view plain

cop

char *getmemory3(int num)  

void test3(void)    

程式在執行的時候用 malloc 申請任意多少的記憶體,程式設計師自己負責在何時用 free釋放記憶體。動態記憶體的生存期由程式設計師自己決定,使用非常靈活。

函式返回區域性變數

一般的來說,函式是可以返回區域性變數的。區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及位址,程式不會出錯。但是如果返回的是區域性變數的位址 指標 的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被...

函式返回區域性變數

一般的來說,函式是可以返回區域性變數的。區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及位址,程式不會出錯。但是如果返回的是區域性變數的位址 指標 的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被...

函式區域性變數的返回

昨天看到一道程式設計糾錯題,在網上看到乙個講解非常詳細的文章,這裡拿來和大家分享一下 一般的來說,函式是可以返回區域性變數的。區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及位址,程式不會出錯。但是如果返回的是區域性變數的位址 ...