1. 程式人生 > >函式返回區域性變數的幾種情況

函式返回區域性變數的幾種情況

本文主要詳細討論了返回返回區域性變數的幾種情況,值得大家注意。

一般的來說,函式是可以返回區域性變數的。 區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及地址,程式不會出錯。但是如果返回的是區域性變數的地址(指標)的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被釋放了,這樣指標指向的內容就是不可預料的內容,呼叫就會出錯。準確的來說,函式不能通過返回指向棧記憶體的指標(注意這裡指的是棧,返回指向堆記憶體的指標是可以的)。

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

1:

  1. #include <stdio.h>   
  2. char *returnStr()   
  3. {   
  4.     char *p="hello world!";   
  5.     return p;   
  6. }   
  7. int main()   
  8. {   
  9.     char *str;   
  10.     str=returnStr();   
  11.     printf("%s\n", str);   
  12.     return 0;   
  13. }  

這個沒有任何問題,因為"hello world!"是一個字串常量,存放在只讀資料段,把該字串常量存放的只讀資料段的首地址賦值給了指標,所以returnStr函式退出時,該該字串常量所在記憶體不會被回收,故能夠通過指標順利無誤的訪問。

2:

  1. #include <stdio.h>   
  2. char *returnStr()   
  3. {   
  4.     char p[]="hello world!";   
  5.     return p;   
  6. }   
  7. int main()   
  8. {   
  9.     char *str;   
  10.     str=returnStr();   
  11.     printf("%s\n", str);   
  12.     return 0;   
  13. }   

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

3:

  1. int func()  
  2. {  
  3.       int a;  
  4.       ....  
  5.       return a;    //允許  
  6. }                     
  7. int * func()  
  8. {  
  9.       int a;  
  10.       ....  
  11.       return &a;    //無意義,不應該這樣做  
  12. }   

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

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

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

期從定義起到程式結束。

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

  1. #include <stdio.h>   
  2. char *returnStr()   
  3. {   
  4.     static char p[]="hello world!";   
  5.     return p;   
  6. }   
  7. int main()   
  8. {   
  9.     char *str;   
  10.      str=returnStr();   
  11.     printf("%s\n", str);   
  12.     return 0;   
  13. }   

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

  1. int* func( void )  
  2. {  
  3.     static int a[10];  
  4.     ........  
  5.     return a;  
  6. }   

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

  1. char *GetMemory3(int num)  
  2. {  
  3. char *p = (char *)malloc(sizeof(char) * num);  
  4. return p;  
  5. }  
  6. void Test3(void)  
  7. {  
  8. char *str = NULL;  
  9. str = GetMemory3(100);  
  10. strcpy(str, "hello");  
  11. cout<str <endl;  
  12. free(str);  
  13. }  

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

相關推薦

函式返回區域性變數情況

本文主要詳細討論了返回返回區域性變數的幾種情況,值得大家注意。 一般的來說,函式是可以返回區域性變數的。 區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及地址,程式不會出錯。但是如果返回的是區域性

C函式返回區域性變數

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

變數的儲存地址分配和函式返回區域性變數相關問題

當一個函式執行完後,內部的區域性變數會被銷燬,因此,在返回函式值時,不要返回區域性變數,否則會出現不知名的錯誤。但是,有的時候又是可以返回區域性變數的,這又是為什麼呢? 來看一下這個例子: 假如定義了一個如下的結構: struct LIST{ int a; int 

C++函式返回區域性變數指標的問題

全域性變數作用域:全域性作用域(全域性變數只需在一個原始檔中定義,就可以作用於所有的原始檔。) 生命週期:程式執行期一直存在 引用方法:其他檔案中要使用必須用extern 關鍵字宣告要引用的全域性變數。 記憶體分佈:全域性資料區 注意:如果在兩個檔案中都定義了相同名字的全域性變數,連接出錯:變數重定義 例子:

函式返回區域性變數問題

           一般的來說,函式是可以返回區域性變數的,但是要注意幾種情況。 區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及地址,程式不會出錯。但是如果返回的是區域性變數的地址(指標)的話,程式

C語言的那些祕密之---函式返回區域性變數

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

socket recv()函式返回0的一情況

假設使用Socket基於TCP通訊協議進行C/S通訊程式設計,客服端已經成功與服務端建立tcp連線,並且可以正常進行收發資料。 當一段時間後,服務端的程式如果呼叫closesocket(sClient);WSACleanup();函式關閉socket,  那麼客戶端的

拿JS非同步函式返回值的方式

在我們的編碼過程中,為了滿足業務需求,經常需要獲取JS非同步函式的返回值。今天就來彙總一下拿值的幾種方式。 1,通過回撥函式的方式來拿返回值,這個想必大家不會陌生 function getSomething(cb) { var r = 0;

函式返回情況

轉載地址:https://www.cnblogs.com/edwardcmh/archive/2012/03/20/2408359.html 1. 返回區域性變數的值 可以有兩種情況:返回區域性自動變數和區域性靜態變數,比如, int func() { int t

Python函式摘要篇(形參方式,區域性變數問題,遞迴等)

函式是什麼? 函式一詞來源於數學,但程式設計中的「函式」概念,與數學中的函式是有很大不同的,具體區別,我們後面會講,程式設計中的函式在英文中也有很多不同的叫法。在BASIC中叫做subroutine(子過程或子程式),在Pascal中叫做procedure(過程)和function,在C中只有f

C++引用做函式引數和函式返回值是引用的情況

引用做函式引數引用的內部實現,是常指標,所以引用其實是對指標做了一些限制,這種限制的意義是在某些應用場景中,使用引用具有更好的 實用性和可讀性。具體講,引用最常見的用處是在做函式引數的時候,對比指標做函式引數,比如:指標做函式引數:void myswap(int *a,int

C++編譯器生成預設的建構函式情況

問題:對c++初學者來說存在一個誤區,如果類沒有定義任何建構函式,編譯器會自動生成預設的建構函式。   注意:這種說法是錯誤的。 正確的說法:惟有預設建構函式”被需要“的時候編譯器才會合成預設建構函式。 那什麼情況下是“被需要”

獲取函式中某個區域性變數物件的所有key值?

題目 在不改變以下程式碼的情況下,如何獲取函式fn中區域性變數obj中所有鍵值? function fn (key) { const obj = { a: 1, b: 2, /* other props */ } return obj[key]; } 分析 可以

geoprocessor(GP)工具提示“對 COM 元件的呼叫返回了錯誤 HRESULT E_FAIL”的情況

以gp工具中的merge工具進行示例分析:1、當引數input所表示的要素型別不一致的時候會出現“對 COM 元件的呼叫返回了錯誤 HRESULT E_FAIL”提示。2、當引數output所表示的要素已存在,且gp工具的overwrite屬性設定為false的時候也會出現

python基礎之四函式型別、函式的巢狀呼叫、函式區域性變數和全域性變數

函式根據有沒有引數,有沒有返回值,可以相互組合,一共有4種 * 無引數,無返回值 * 無引數,有返回值 * 有引數,無返回值 * 有引數,有返回值 <1>無引數,無返回值的函式此類函式,不能接收引數,也沒有返回值,一般情況下,列印提示燈類似的功能,使用這類的函式 def pr

返回型別是引用型別的情況

/* 返回值型別 基本型別:(基本型別太簡單,我不準備講解) 引用型別: 類:返回的是該類的物件 抽象類:返回的是該抽象類的子類物件 介面: */ abstract class Person { public abstract void study(); }

ARM異常中斷返回情況

重要基礎知識:R15(PC)總是指向“正在取指”的指令,而不是指向“正在執行”的指令或正在“譯碼”的指令。一般來說,人們習慣性約定將“正在執行的指令作為參考點”,稱之為當前第一條指令,因此 PC總是指向第三條指令。當 ARM 狀態時,每條指令為 4 位元組長,所以 PC 始

thinkphp模板變數輸出的情況及注意點

其實在thinkphp中模板變數輸出是有幾種不同的情況的,剛開始接觸thinkphp的時候不是很瞭解,現在來稍微總結一下。 第一種將某個標籤的name屬性作為變數,這個時候在模板中這個變數的寫法是像

函式區域性變數返回

原文連結:http://blog.csdn.net/jackystudio/article/details/11523353 一般說來,函式中是可以進行區域性變數的返回的,不然豈不是全部要用全域性變數,如果使用了全域性變數,那還有必要進行返回嗎?那函式就沒有它存在的意義了!但是要注意了,這裡所謂的區域性

呼叫拷貝建構函式情況

通常建構函式只在物件建立時被呼叫,而拷貝建構函式則在以下3種情況下被呼叫。 1、當使用類的一個物件去初始化該類的另一個新物件時。 2、如果函式的形參是類的物件,那麼當呼叫該函式時拷貝建構