c/c++排坑(4) -- c/c++中返回局部變量


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM