回覆列表
  • 1 # TonyDeng

    函式返回的是值,這個值可以是指標或引用,但不管是指標還是引用,所指向的物件都不能是存在於棧中的,可以存在於堆中,即可以返回指向堆物件的指標,不可以返回指向棧物件的指標,引用亦然。

    資料在棧中,是會被後續程式碼使用,但並不必然被用到所指向的位置,它有機會是仍然可尋並存在的,故此不能因為某些“試驗”可以找到這些資料就認為必然可以如此。

    棧空間使用壓入式後進先出機制,資料會自動銷燬(最先入的未必會被彈出銷燬故有僥倖被返回指標尋訪的機會),堆空間是不會自動銷燬資料的,這就是用mallic()之類動態分配函式得到的物件必須主動用free()銷燬的原因,忘了這個動作,就是所謂的記憶體洩漏(資料霸佔堆空間或因指標丟失而無法尋訪),指標的風險實際上也在這裡。

  • 2 # 重慶葉宏

    C/C++結構體返回時,明顯克隆了一份,就象返回一個整數似的理解。這克隆出的一份結構體,應該在呼叫者的棧中。

  • 3 # 蝸牛怪

    首先說明一個問題,雖然返回值在函式內部聲名並且使用,但函式返回值在返回前從原變數進行資料的轉移,這是因為函式呼叫完畢,其棧要進行回收,這時棧裡面的記憶體變值雖然還可以訪問,但其已經標記為回收(因為函式返回後或呼叫完畢後esp棧進行了平衡,關於函式呼叫方式,我錄了一個影片,你可以點選檢視)。

    下面我們來說一下函式的返回值,在返回時這個值的轉移問題:

    當函式的返回值型別為基本資料型別時(雙精度浮點型以及非標準的__int64型別除外)作為返回值時,透過暫存器eax來儲存返回的資料,而對構體或者類物件等複雜資料屬於自定義型別,暫存器eax無法儲存物件中的所有資料,所以在函式返回時,暫存器eax無法滿足需求。

    對於暫存器eax無法儲存返回的資料型別時,在函式呼叫前,編譯器會預先將要返回的資料記憶體空間使用的棧(注意,這裡是呼叫者的棧空間預留)保留出來,這樣當函式在退出時,將返回值的資料複製到預先分配的記憶體棧空間,以這個臨時空間的首地址作為首地址作為返回值。由於這個臨時空間是呼叫者函式內部的棧空間,所以說是可用的。

    下面我將一段程式碼為例:

  • 4 # Hypervisor

    因為函式的返回值並不會放在記憶體中,更不會當到棧中,而是放到了CPU內部的通用暫存器裡面,具體是放在哪個暫存器,就要看那個CPU的架構了,X86的話,是放在了eax暫存器和edx暫存器中。

  • 5 # 懶蟲o重複了o

    這樣做90%是錯誤的。

    1.指標是一個記憶體地址,當函式執行完畢就會釋放區域性變數,這個指標指向的地址就會出錯,函式外面再訪問這個地址就會出錯。

    2.結構。當函式返回會將區域性變數賦值給你函式外的變數,然後就釋放這個區域性變數。例如std::string。

    std::string test(){

    std::string a=“abc”; //區域性變數a

    return a;}

    void main(){

    std::string b = test(); //變數b,函式返回時會將區域性變數a賦值給b

    //

    printf(b.c_str()); //這裡訪問不會出錯

    }

    但這種方法和其他語言互調時會有相容問題。

    剩下的%10

    例如gethostbyname函式內部是將值儲存在一個全域性變數裡。所以返回指標不會出現問題。呼叫完gethostbuname再訪問他的返回值不會記憶體出錯。但這種方法會出現執行緒同步問題。也不推薦使用這種方法。

    想要返回指標必須是函式內部用malloc或new申請記憶體,在函式體內不釋放,在函式外呼叫釋放即可。弊端是容易造成記憶體溢位。想要解決記憶體溢位就使用智慧指標。

  • 中秋節和大豐收的關聯?
  • 女人在什麼時候最令人討厭?為什麼?