深入探究函数返回局部变量
一般的來說,函數(shù)是可以返回局部變量的。 局部變量的作用域 只在函數(shù)內(nèi)部,在函數(shù)返回后,局部變量的內(nèi)存已經(jīng)釋放了。因此,如果函數(shù)返回的是局部變量的值,不涉及地址,程序不會出錯。但是如果返回的是局部變量的地址(指針)的話,程序運行后會出錯。因為 函數(shù)只是把指針復(fù)制后返回了,但是指針指向的內(nèi)容已經(jīng)被釋放了,這樣指針指向的內(nèi)容就是不可預(yù)料的內(nèi)容,調(diào)用就會出錯。準(zhǔn)確的來說,函數(shù)不能通過返回指向棧內(nèi)存的指針(注意這里指的是棧,返回指向堆內(nèi)存的指針是可以的)。
?
其實就是這個意思,不是說函數(shù)可以返回值,不能返回指針。而是,關(guān)鍵是看看返回的指針指向的值的內(nèi)容是否在函數(shù)返回之后還依然未被釋放。
比如static修飾的局部變量是在靜態(tài)全局區(qū)域,堆內(nèi)存,文字常量區(qū)域也叫只讀區(qū)域,列舉的這幾個區(qū)域就是可以通過指針來返回,
當(dāng)然值也是可以返回的,因為值是有備份。
不能返回的,也僅僅是局部變量在棧空間中的東西,因為這些東西在函數(shù)結(jié)束的時候是會被清空。
?
??? 下面以函數(shù)返回局部變量的指針舉幾個典型的例子來說明:
1:
?
[cpp] #include?<stdio.h>? ??這個沒有任何問題,因為"hello?world!"是一個字符串常量,存放在只讀數(shù)據(jù)段,把該字符串常量存放的只讀數(shù)據(jù)段的首地址賦值給了指針,所以returnStr函數(shù)退出時,該該字符串常量所在內(nèi)存不會被回收,故能夠通過指針順利無誤的訪問。
?
?
?
2:
?
[html] #include?<stdio.h>???"hello?world!"是局部變量存放在棧中。當(dāng)returnStr函數(shù)退出時,棧要清空,局部變量的內(nèi)存也被清空了,所以這時的函數(shù)返回的是一個已被釋放的內(nèi)存地址,所以有可能打印出來的是亂碼。?
?
?
3:
?
[html] int?func()???
局部變量也分局部自動變量和局部靜態(tài)變量,由于a返回的是值,因此返回一個局部變量是可以的,無論自動還是靜態(tài),
因為這時候返回的是這個局部變量的值,但不應(yīng)該返回指向局部自動變量的指針,因為函數(shù)調(diào)用結(jié)束后該局部自動變量
被拋棄,這個指針指向一個不再存在的對象,是無意義的。但可以返回指向局部靜態(tài)變量的指針,因為靜態(tài)變量的生存
期從定義起到程序結(jié)束。
4:如果函數(shù)的返回值非要是一個局部變量的地址,那么該局部變量一定要申明為static類型。如下:
5: 數(shù)組是不能作為函數(shù)的返回值的,原因是編譯器把數(shù)組名認(rèn)為是局部變量(數(shù)組)的地址。返回一個數(shù)組一般用返回指向這個數(shù)組的指針代替,而且這個指針不能指向一個自動數(shù)組,因為函數(shù)結(jié)束后自動數(shù)組被拋棄,但可以返回一個指向靜態(tài)局部數(shù)組的指針,因為靜態(tài)存儲期是從對象定義到程序結(jié)束的。 如下:
?
?
[html]6:返回指向堆內(nèi)存的指針是可以的
?
[html] char?*GetMemory3(int?num)??程序在運行的時候用 malloc 申請任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時用 free釋放內(nèi)存。動態(tài)內(nèi)存的生存期由程序員自己決定,使用非常靈活
轉(zhuǎn)載于:https://www.cnblogs.com/pangblog/p/3292137.html
總結(jié)
以上是生活随笔為你收集整理的深入探究函数返回局部变量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SqlServer判断数据库、表、存储过
- 下一篇: 文档生成工具Sandcastle Hel