由返回區域性指標問題引起的思考

2021-08-26 10:31:48 字數 1069 閱讀 3947

我們大家都知道指標函式的返回指標不能指向函式內的自動變數,如果需要返回函式的內部變數的話,就需要將該變數宣告為靜態變數。為什麼函式能夠返回靜態變數的位址而不能返回區域性自動變數的位址,到底什麼樣的物件能夠返回其位址,而什麼樣的物件不能夠返回其位址?靜態變數與區域性自動變數的主要區別是什麼?

要想明白這些就需要理解程式的記憶體布局情況

程式的儲存區域分為:**段、唯讀資料段、已初始化的讀寫資料段、未初始化的資料段、堆、棧。

1、**段、唯讀資料段、已初始化的讀寫資料段、未初始化的資料段都屬於靜態區域。

2、堆記憶體只在程式執行時出現,一般有程式設計師分配和釋放。

3、棧記憶體只在程式執行時出現,在函式內部使用的變數,函式引數以及返回值將使用棧空間。

到底儲存在靜態區域和儲存在棧區域的物件在返回指標的函式中有什麼本質區別,為什麼儲存在靜態區域的靜態變數就能夠返回其位址,而儲存在棧區域的自動變數不能返回其位址?

主要在於他們的管理機制不同,儲存在靜態區域的物件的生存週期是主函式的生存週期,而儲存在棧區域的物件生存週期為指標函式開始執行到指標函式結束,當指標函式結束時儲存在棧區域的物件生存週期也就結束,其位址也變成無效位址。棧空間由編譯器自動分配和釋放,函式結束時其棧空間釋放記憶體。堆區域一般由程式設計師來控制其生存週期。因此,指標函式返回的指標能夠指向靜態區域的變數而不能指向自動區域性變數。

當函式使用指標作為返回值時,它可以指向靜態區域的位址,可以指向堆記憶體的位址,也可以指向函式呼叫者的棧空間,但是它不可以指向乙個函式內部棧記憶體的位址。

因此,能不能返回區域性指標變數,不在於這個指標變數的型別和性質(不在於該指標是不是區域性指標變數),而在於該指標指向的物件的型別和性質。如果該指標指向函式內部的棧空間,則程式非法,如果指向靜態區域的位址,則合法。

因此,判斷指標函式返回值是否合法,應該首先看看該返回指標變數指向的物件的儲存區域,即該指標指向的區域。透過現象看本質,不同區域的物件本質區別在於其的生存週期的有效性不同,判斷返回的指標值是否有效合法,最本質應該看看該指標指向的物件的生存週期在函式結束後是否有效。如果該物件的生存週期長於指標函式的生存週期,則該指標返回值合法,否則,該指標的值為非法位址。即使該指標指向堆區域的位址但在指標函式結束時,堆已釋放,則該函式的返回位址仍為非法。

由「認知窄化」引起的思考

由 認知窄化 引起的思考 2010年04月27日 第一次接觸 perceptural narrowing 是在發展心理學的課上。聽陶老師說,因為國內還比較少人做這方面的研究,於是還沒人把這個詞很好的用中文意思來闡釋。姑且稱為 認知窄化 吧。這讓我想了很多很多,是不是隨著年齡的增長,我的一種認知能力就...

由HR標籤樣式引起的思考

今天同學問了我乙個問題,大體是這樣的。在加了hr後,在ie下面會有預設的6px的邊距,通過修改了margin 6px 後仍然能解決,但是firefox下面卻發現,hr提上去了,很不和諧。上網看了類似的問題,看到了。這又是不同瀏覽器的預設邊距問題。解決方法 hr解釋 當ie下面解析的時候,會解析mar...

C 函式返回區域性變數指標的問題

講這個問題之前要先簡單講一下c 的記憶體管理。更詳細的內容可以參考這篇文章 c 記憶體管理 c 程式的記憶體被分為堆 heap 棧 stack 全域性 靜態儲存區,自由儲存區和常量儲存區。1 堆 heap new的都存放在這裡,屬於動態分配,如果在程式中呼叫delete釋放掉,那麼將一直存在,直到程...