c/c++排坑(4) -- c/c++中返回區域性變數
阿新 • • 發佈:2018-12-09
返回c語言中的區域性變數
先看一段程式碼猜猜,列印值:
#include <iostream> using namespace std; char * func(); int main() { char *buf = func(); cout << "buf:" << buf << endl; } char * func() { char buffer[3]; buffer[0] = '1'; buffer[1] = '2'; buffer[2] = '3'; return buffer; }
或許你已經猜到了,會列印亂碼的值。原因是返回了一個區域性的變數,而區域性變數再離開函式體之後就不存在了,char 指標指向不明的空間。那麼如何改進這玩意兒呢?
- 返回一個指向字串常量的指標。
char * func() { return "123"; }
- 使用全域性宣告的陣列。
這適用於自己建立的字串情況,也很簡單易用。它的缺點在於任何人都有可能在任何時候修改這個全域性陣列,而且該函式的下一次呼叫也會覆蓋該陣列的內容。 - 使用靜態陣列。
這就可以防止任何人修改這個值,但是該函式的下一次呼叫將覆蓋整個陣列的內容,所以呼叫者必須在此之前使用或備份資料的內容。和全域性陣列一樣,大型緩衝區如果閒置不用是非常浪費記憶體空間的。
char * func()
{
static char buffer[3];
buffer[0] = '1';
buffer[1] = '2';
buffer[2] = '3';
return buffer;
}
- 顯示分配一些記憶體,儲存返回的值。整個方法其實挺不錯的,但是缺點也非常明顯,程式設計師必須承擔記憶體管理的責任。我的天,在函式外還能想著給函式內的記憶體做釋放的傢伙得多變態。所以...嗯...我是受不了這種做法。
char * func() { char * buffer = malloc(10); ... return buffer; }
- 呼叫者分配記憶體來儲存函式的返回值。為了提高安全性,呼叫者應該同時指定緩衝區的大小。
char * func(char * result, int size)
{
...
strncpy(result, "something", size);
}
buffer = malloc(size);
func(buffer, size);
...
free(buffer);
如果程式設計師可以在同一程式碼中同時進行malloc和free操作,記憶體管理是較為輕鬆的。
C++的一些情況
C++中當然在普通情況下和c無異。但是考慮如下程式碼,看看會列印啥:
#include <iostream>
#include <string>
using namespace std;
string func1();
int main()
{
string str = func1();
cout << "str:" << str << endl;
}
string func1()
{
string str("str123");
return str;
}
哈哈,顯然你已經猜到不會列印亂碼了。為啥同樣是區域性變數,string型別不會列印亂碼呢。這是因為在C++中,返回的時候會有一個臨時變數來儲存這個返回值哦。同樣的在輸入的時候也是通過生成臨時變數傳參的。考慮如下程式碼:
void func(Object obj)
{
...
}
如果Object 是一個複雜的物件,那麼其實是非常影響效能的,可考慮改成如下的程式碼:
void func(const Object &obj)
{
...
}
咦,是不是很熟悉呢。其實很多程式碼都是這樣做的哈。這裡的const表示不可修改,其實const關鍵字還真是容易讓人理解錯呢,將const理解成readonly大多數情況下不會錯。
See you next time. Happy Coding!!!
我的github