遇到過好幾次關於函數返回指針變量問題,有時候是可以的,有時候是不可以的,然后就混亂了。今天研究了下,結果發現原來和內存分配有關。
用下面的例子分析下吧:
char * test() { char a[] = "abc"; char * p =a; return p; } int main() { printf("%s",test()); return 0; }
這段p是局部指針,指向局部數組a,這種情況輸出為空或者奇怪字符串。
分析:
a是局部數組,系統為其分配的是棧內存,test()函數一結束,a的生命結束,其所占內存被釋放,p也被釋放,返回回來的是被釋放的內存,輸出必然不正確。
char * test() { char * p ="abc"; return p; } int main() { printf("%s",test()); return 0; }
這段輸出是"abc"。
為什么這樣又是正確的呢?
因為p雖然為局部指針,函數結束,p被釋放,但是p指向的並不是棧內存,而是常量存儲區,即使函數結束,這段內存存儲的仍舊是"abc",所以返回回來的地址是有效的,結果自然是正確的。
再用一個strcpy函數的實現來舉例:
char * strcpy(char * strDest,const char * strSrc) { assert(strDest != null && strSrc != null); char * address = strDest; while(*strDest++ = *strSrc++); return address; }
顯然,返回的也是局部指針address,並且是正確的。
因為address指向的地址是strDest所指地址,而strDest指向的地址是作為參數傳給函數的,所以即便函數結束,釋放了address,但返回的地址仍舊是有效的,即目的地址。
總結:返回局部指針時,要依據其指向的地址,在函數退出后是否有效來判斷返回是否是想要得到的結果。
