返回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