2017-04-23 66 views
3

我碰到this page,它說明了創建懸掛指針的常見方法。fflush()在懸掛指針方面做了什麼?

下面是使用局部變量的返回地址說明懸擺指針代碼:

在運行這個,這是編譯器警告我得到(預期):

In function 'fun': 
12:2: warning: function returns address of local variable [-Wreturn-local-addr] 
    return &x; 
^

這是輸出我得到(到目前爲止好):

32743 

然而,當我合作mment了fflush(標準輸出)線,這是輸出我得到(使用相同的編譯器警告):

5 

什麼是這種現象的原因? fflush命令的存在/缺失如何導致此行爲更改?

+1

http://stackoverflow.com/a/6445794/12711 –

+0

「*什麼是對這種行爲的原因是什麼?*」這是**未定義行爲**。你使用'fflush'是無關緊要的。 ('fflush'清空'stdout'的內容,但由於您沒有緩衝內容,所以它沒有任何合法的用途)。你可能會得到'5',你可能會得到一個'Segmentation Fault',它是** Undefined **。 –

回答

3

返回一個指針到堆棧上的對象是不好的,因爲你所提到的。您只會看到fflush()調用存在問題的原因是,如果該堆棧不存在,堆棧將不會被修改。也就是說,5仍然存在,所以指針解引用仍然給你5。如果你調用一個函數在funprintf之間(幾乎所有的功能,可能),它幾乎肯定會覆蓋該堆棧單元,使得後來值訪問任何垃圾該功能發生了離開那裏。

+0

不會printf()也放在棧上?這會導致指針指向的地址被其他東西(可能)覆蓋? – Arpith

+0

任何事情都是可能的。顯然,這不會發生在你的情況,但。 –

+0

我明白了。嘗試了一個簡單的睡眠(1),並做到了這一點。感謝您的幫助@CarlNorum – Arpith

0

這是因爲調用fflush(stdout)寫入到堆棧,其中x了。

讓我解釋一下。彙編語言中的堆棧(這是所有編程語言最終以這種或那種方式運行的)通常用於存儲局部變量,返回地址和函數參數。當函數被調用時,它將這些東西推入堆棧:

  • 函數完成後繼續執行代碼的地址。
  • 的參數的功能,在由所使用的調用約定確定的順序。
  • 函數使用的局部變量。然後

這些東西被彈出棧,一個接一個,通過簡單地改變在這裏CPU認爲堆棧的頂部是。這意味着數據仍然存在,但不能保證繼續存在。

fun()之後調用另一個函數覆蓋堆棧頂部以上的值,在這種情況下值爲stdout,因此指針的參考值發生更改。

如果不調用另一個函數,該數據保持在那裏當指針被廢棄仍然有效。

+2

我在系統上編碼了一次,其中堆棧未用於局部變量和函數參數 –

+0

如果OP在x86或x86-64系統(大多數個人計算機)上編程,則使用堆棧局部變量和函數參數。如果他們在嵌入式系統上進行編程,那麼理想情況下OP應該知道他們選擇的系統的特質,並相應地採取行動。無論如何,返回一個指向局部變量的指針是未定義的行爲。 – InternetAussie