初識函式堆疊幀

如上圖可見,函式在被呼叫的時候會現在堆疊上開辟一個空間,我們稱之為堆疊幀,之后函式內部的變數在這塊區域進行空間開辟,
但是函式在呼叫的時候,怎么知道需要開辟多大空間呢???
void func()
{
int a, b;
double c, d, e;
}
按照示例代碼,會先對需要的記憶體空間大小進行預估,然后進行空間開辟,
函式回傳時,堆疊幀會被釋放,但是,雖然堆疊幀被釋放,里面的內容是不會被清空的,下面通過以下的例子進行分析,
#include <stdio.h>
#include <windows>
char* show()
{
char str[] = "hello world!";
return str;
}
int main()
{
char* s = show();
printf("%s\n", s);
system("pause");
return 0;
}
運行會得到亂碼的結果

看到這里,有些小伙伴肯定會說,嗷,return陳述句是不可以回傳指向堆疊記憶體的指標的,
可是這又是為什么呢?
于是我按下F11進行除錯,發現當代碼進行到printf陳述句行的時候,s指向的內容依舊是hello world!,繼續F10,到14行的時候,printf函式被呼叫,s字串居然又不存在了!!!!
其實,printf也是個函式,也會在呼叫函式的時候形成堆疊幀,會覆寫曾經show堆疊幀存在的位置,而show堆疊幀在被釋放之后是無效的,
return
接下來,讓我們把關注點放到return關鍵字,同樣的,從代碼出發~~

誒,那就奇怪了???上面不是說過函式堆疊幀會被釋放嗎,那x的值又是怎么被y拿到的呀???
函式的回傳值其實是通過暫存器的方式回傳給呼叫方的
同樣的,讓我們看看除錯,

這是進入了GetData函式的匯編語言,eax其實就是暫存器,14行下一行的意思就是把x的內容放入暫存器里,
然后我們繼續F11

回到了main函式,發現eax會把值再次放入y中,
看到這里是不是恍然大悟了呢!!!
來看另外一種情況,如果回傳的值不被接收呢???

如果回傳的值不被接收,GetData后續沒有處理eax,
個人總結環節
最后,來把知識點系統回顧一遍!

return回傳值本質上是通過暫存器回傳的,如果回傳的是一個值,在有變數接收該回傳型別的情況下,可以列印該資料,如果回傳的是一個指標,雖然可以接收到回傳的地址,但是原來函式堆疊幀存在的位置會被覆寫,指標所指向的內容會在此時被改變,所以說,return陳述句不可以回傳指向堆疊記憶體的指標,該函式堆疊幀在結束時即被銷毀,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/301819.html
標籤:其他
上一篇:C語言進階:字串和記憶體函式
下一篇:我喜歡你時的內心活動
