Bug 返回區域性物件的引用或指標

2021-08-17 22:50:47 字數 2224 閱讀 1298

昨天晚上,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 這句呼叫的是預設的拷貝建構函式,如果是自己重新...