話說 當C++函式回傳型別為參考時 要求在函式的引數中,包含有以參考方式或指標方式存在的,需要被回傳的引數。
但是為什么下面的代碼也能正常編譯運行?
int& f(int a,int b,int c)
{
c = a + b;
return c;
}
int main() {
cout << f(1,1,0) << endl;
}
是我對這句話理解出了問題還是這句話說錯了?
uj5u.com熱心網友回復:
但是有的時候,我們會發現,你即使是回傳變數的參考,你在呼叫函式的時候,也會發現可以回傳正確值,比如說上面的這個程式中的 函式,在main函式中呼叫的時候,也能回傳正確的值。這個并推翻上面的結論,只能說明你的程式太小了。因為原來儲存 區域變數 的那段地址空間還沒有被別的代碼應用,里面存盤的值還沒有被覆寫,所以才會得到正確的結果。 如果折這段地址空間被分配給別的代碼使用,那么就會出現錯誤了。從上面的代碼測驗結果中也是可以發現的,就是如果子函式回傳一個指標的話,在主函式中呼叫的時候,你會發現回傳值和回傳臨時變數的地址是一樣的,但是存放的內容變成了一個隨機值
uj5u.com熱心網友回復:
你那句話的理解錯誤了,那句話的意思是說,函式引數回傳值,不是函式回傳值,要使函式引數可以充當回傳值,通常系指標或者參考的方式作為函式引數傳入函式uj5u.com熱心網友回復:
你的函式回傳了一個區域變數的參考,有潛在危險。就像陣列越界,當然能通過編譯,但結果不一定正確或者運行崩潰。
uj5u.com熱心網友回復:
買彩票有中獎的,但是想發家致富的能靠買彩票嗎?uj5u.com熱心網友回復:
編譯是沒問題,但你回傳了區域變數的參考,這個變數記憶體在f函式結束后就銷毀了,如果你之后繼續訪問這個變數就可能引起崩潰或出錯uj5u.com熱心網友回復:
此外,用程式沒出錯來推不出正確,最多說明運氣好而已uj5u.com熱心網友回復:
回傳型別跟函式引數沒有關系,你在哪看到的這要求。編譯通過不代表運行時沒問題,c是區域變數,不應該回傳區域變數的參考。
uj5u.com熱心網友回復:
堆疊中的變數通常包括函式引數和函式里宣告的臨時變數。堆疊中的基本變數退出其作用域時,沒有誰執行一段代碼去釋放/銷毀/析構它所占用的記憶體,僅僅是沒人再去理會的留在當前堆疊頂上方的若干遺留下來可被后續壓堆疊操作覆寫的無用資料而已。
而堆疊中的類變數退出其作用域時,會自動執行其解構式,……
其實電腦開機后物理記憶體的每個位元組中都有值且都是可讀寫的,從來不會因為所謂的new、delete或malloc、free而被創建、銷毀。區別僅在于作業系統記憶體管理模塊在你讀寫時是否能發現并是否采取相應動作而已。作業系統管理記憶體的粒度不是位元組而是頁,一頁通常為4KB。
uj5u.com熱心網友回復:
可以編譯,但是有隱患。可以同時看看,c在函式函式里外,存放的地址uj5u.com熱心網友回復:
臨時量的生存期是從它出現到完整運算式的結束。C++語言的設計和演化里是這么說的——

所以你的程式是可以正常運行的,這是符合規范的。
uj5u.com熱心網友回復:
回傳對區域變數的參考沒有語法錯誤,不過地址是野的。如果是為了避免回傳很大的物件實體導致性能損失,可以采用C++11的右值參考,
return std::move(string)
uj5u.com熱心網友回復:
區域變數的參考,出了作用域,就不被記錄了,但是基本型別的資料并沒有被清空,用以參考的地址還能用,就是很可能運行后,會出錯。就是所謂的“暫時能用”的“野指標”吧。
請大神指正。
uj5u.com熱心網友回復:
大神已經在8樓指正過了。

http://edu.csdn.net/course/detail/2344 C語言指標與匯編記憶體地址-一.代碼要素
uj5u.com熱心網友回復:
哈哈哈,大神你好!!
只是鏈接地址看不了啊!只能會員。
uj5u.com熱心網友回復:
那就“維持現狀”或加入會員。宣告:我不是CSDN的托兒。
uj5u.com熱心網友回復:
如果輸入的引數中是 "(...int &c)" ;是不是也是正確安全的?請大神指正uj5u.com熱心網友回復:
請參考《C++函式的回傳值(上)》希望能夠幫到您!
uj5u.com熱心網友回復:
雖然編譯通過,而且運行也沒出錯,但是這是錯誤的寫法,g++會有警告的demo2.cpp: In function 'int& f(int, int, int)':
demo2.cpp:1:24: warning: reference to local variable 'c' returned [-Wreturn-local-addr]
int& f(int a,int b,int c)
uj5u.com熱心網友回復:
CB里報錯:[C++ Error] 2021_1_25_Unit1.cpp(10049): E2363 Attempting to return a reference to local variable 'c'如果輸入的引數中是 "(...int &c)" ;是不是也是正確安全的?請大神指正
int& f(int a,int b,int& c)
{
cout<<c<<endl; //4
c = a + b;
return c;
}
int main() {
int c=4;
cout << f(1,1,c) << endl;//2
cout<<c<<endl; //2
system("pause");
}
uj5u.com熱心網友回復:
這樣的代碼根本不會說明問題改一下#include <iostream>
using namespace std;
#pragma warning(disable:4996)
class A {
char* _data;
public:
A(const char* s) :_data(strdup(s)) {
}
A(const A& str) {
_data = strdup(str._data);
}
A() :_data(nullptr) {
}
A(A&& rh) {
swap(_data, rh._data);
}
~A() {
delete _data;
}
A& operator=(const A& rh) {
if (this != &rh) {
if (_data != nullptr)
delete _data;
_data = strdup(rh._data);
}
return *this;
}
A& operator=( A&& rh) {
swap(this->_data, rh._data);
return *this;
}
friend ostream& operator<<(ostream& out, const A& rh);
};
ostream& operator<<(ostream& out, const A& rh) {
out << rh._data;
return out;
}
A& func(const char* str) {
A result(str);
return result;
}
int main()
{
cout << func("123");
}
你會發現新的編譯器會報警告,運行會出錯。因為func函式的回傳值 result在列印前被析構了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/271009.html
標籤:C++ 語言
下一篇:求大佬幫助,c++的一個實驗專案
