昨天晚上,si
sts is
t的宋教授在 si
sts is
t乙個官方研招群裡分享了乙個 bu
g bug
,如下圖:
**如下:
一開始我覺得沒問題啊,怎麼會出現段錯誤呢?並且 ne
w new
怎麼可能不是 ne
w new
乙個 he
aph ea
p物件?(後來得知教授的意思是 ss
s
s無法 ne
w new
到堆上讓他保持)
之所以有這樣的疑問,也是因為雖然我經常用 c+
+ c++
,但是多數都是用來做 oj
o
j題目,所以並不常用工程專案中所用到的一些用法,也就缺乏這方面的經驗。
宋教授告訴我是因為 ob
ject
life
time
o bj
ectl
ifet
ime,可是我一下子並沒有想明白為什麼,於是嘗試去還原一下 bu
g bug
,如下是還原後的**及編譯情況:
在不加 st
atic
s ta
tic的情況下,產生了段錯誤,不過直接原因並不像有的學長說的那樣,是因為返回了 ne
w new
物件,這只是間接原因,真正的原因是 ss
s
s,因為 ss
s
s是乙個 st
d::is
trea
m std
::ist
ream
物件,不能拷貝只能引用,所以在 re
ader
(ss)
r ea
der(
ss)裡傳遞過去了 ss
s
s的引用,這也是我們題目中所說的返回區域性物件的引用的 bu
g bug
之所在,不過為什麼如此這般就是 bu
g bug
呢?在這裡我們需要簡單說一些區域性物件的生命週期(l
ifet
ime)
( li
feti
me),我們在函式 ma
ke_r
eade
r() mak
e_re
ader
()中宣告的兩個物件 s1
s
1和 ss
s
s都是區域性物件,在這個函式結束後,這兩個區域性物件的生命週期也就結束了,被銷毀了。待到我們呼叫這個函式返回的 re
ader
∗ rea
der∗
中的 ss
s
s引用時,很容易發現 ss
s
s本體都已經被銷毀了,引用還有什麼存在的意義呢,如果非要說他存在的意義,那就是造成段錯誤。由於區域性物件是放在段裡的,所以引用指向的也是段裡,當段裡的物件被銷毀時,引用也就造成了段錯誤。
那麼這種問題怎麼解決呢?
根據剛才的分析是因為區域性物件生命週期結束導致的,那麼我們可以想辦法改變他的生命週期,方法之一就是 st
atic
s ta
tic,這樣他的生命週期就貫穿整個程式,也就不會出現段錯誤了。
不過個人感覺這樣做欠妥,因為加上 st
atic
s ta
tic的時候他只會在第一次呼叫時真正的執行,後續的呼叫時都會沿用上一次的狀態,這樣是否會造成混亂呢?
返回區域性物件的引用的 bu
g bug
我們可能已經講得十分清楚了,指標同理。
返回指向區域性變數的指標或引用
返回區域性變數沒問題 如果返回區域性變數有問題,函式的意義還有嗎?全域性變數還用返回嗎?返回指向區域性變數的指標才有問題 函式退棧之後,區域性變數消失,指標將指向未知區域,所以出現問題。返回區域性變數的引用也是絕對不可以的 引用只是變數的乙個別名,變數本體都不存在了,引用當然也沒有任何意義。還有,如...
函式返回區域性變數的指標或引用
一般來說,由於在離開函式後區域性變數會被釋放,所以是不允許函式返回指向區域性變數的指標或引用的。我們往往需要遵循如下原則 引用作為返回值,必須遵守以下規則 1 不能返回區域性變數的引用。主要原因是區域性變數會在函式返回後被銷毀,因此被返回的引用就成為了 無所指 的引用,程式會進入未知狀態。2 不能返...
c 返回函式區域性物件的引用
在上面的 中,最後能夠輸出正確的值,然而在函式getnode 中,str是乙個區域性的物件,記憶體空間在棧上,當函式退出時,str的記憶體空間被 這是在高階語言的層面上講的。但是為什麼最後的結果是正確的?原因就是node newnode getnode 這句呼叫的是預設的拷貝建構函式,如果是自己重新...