函式返回區域性變數的幾種情況
本文主要詳細討論了返回返回區域性變數的幾種情況,值得大家注意。
一般的來說,函式是可以返回區域性變數的。 區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及地址,程式不會出錯。但是如果返回的是區域性變數的地址(指標)的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被釋放了,這樣指標指向的內容就是不可預料的內容,呼叫就會出錯。準確的來說,函式不能通過返回指向棧記憶體的指標(注意這裡指的是棧,返回指向堆記憶體的指標是可以的)。
下面以函式返回區域性變數的指標舉幾個典型的例子來說明:
1:
- #include <stdio.h>
- char *returnStr()
- {
- char *p="hello world!";
- return p;
- }
- int main()
- {
- char *str;
- str=returnStr();
- printf("%s\n", str);
- return 0;
- }
這個沒有任何問題,因為"hello world!"是一個字串常量,存放在只讀資料段,把該字串常量存放的只讀資料段的首地址賦值給了指標,所以returnStr函式退出時,該該字串常量所在記憶體不會被回收,故能夠通過指標順利無誤的訪問。
2:
- #include <stdio.h>
- char *returnStr()
- {
- char p[]="hello world!";
- return p;
- }
- int main()
- {
- char *str;
- str=returnStr();
- printf("%s\n", str);
- return 0;
- }
"hello world!"是區域性變數存放在棧中。當returnStr函式退出時,棧要清空,區域性變數的記憶體也被清空了,所以這時的函式返回的是一個已被釋放的記憶體地址,所以有可能打印出來的是亂碼。
3:
- int func()
- {
- int a;
- ....
- return a; //允許
- }
- int * func()
- {
- int a;
- ....
- return &a; //無意義,不應該這樣做
- }
區域性變數也分區域性自動變數和區域性靜態變數,由於a返回的是值,因此返回一個區域性變數是可以的,無論自動還是靜態,
因為這時候返回的是這個區域性變數的值,但不應該返回指向區域性自動變數的指標,因為函式呼叫結束後該區域性自動變數
被拋棄,這個指標指向一個不再存在的物件,是無意義的。但可以返回指向區域性靜態變數的指標,因為靜態變數的生存
期從定義起到程式結束。
4:如果函式的返回值非要是一個區域性變數的地址,那麼該區域性變數一定要申明為static型別。如下:
- #include <stdio.h>
- char *returnStr()
- {
- static char p[]="hello world!";
- return p;
- }
- int main()
- {
- char *str;
- str=returnStr();
- printf("%s\n", str);
- return 0;
- }
5: 陣列是不能作為函式的返回值的,原因是編譯器把陣列名認為是區域性變數(陣列)的地址。返回一個數組一般用返回指向這個陣列的指標代替,而且這個指標不能指向一個自動陣列,因為函式結束後自動陣列被拋棄,但可以返回一個指向靜態區域性陣列的指標,因為靜態儲存期是從物件定義到程式結束的。如下:
- int* func( void )
- {
- static int a[10];
- ........
- return a;
- }
6:返回指向堆記憶體的指標是可以的
- char *GetMemory3(int num)
- {
- char *p = (char *)malloc(sizeof(char) * num);
- return p;
- }
- void Test3(void)
- {
- char *str = NULL;
- str = GetMemory3(100);
- strcpy(str, "hello");
- cout<< str << endl;
- free(str);
- }
程式在執行的時候用 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、如果函式的形參是類的物件,那麼當呼叫該函式時拷貝建構