簡體   English   中英

未初始化的變量如何獲得隨機值?

[英]How does an uninitialized variable get a random value?

假設我聲明了一個變量x並保持未初始化狀態。 我繼續打印它的價值。 我看到一些垃圾。

它從何而來? 為什么它不用於生成隨機數? 我的意思是代替使用偽隨機生成器。

“隨機”值就是該位置內存中的內容。 當存儲器被釋放時,通常不會被擦除/清零,因此無論存在什么都會被覆蓋,直到它被覆蓋。

垃圾可能來自兩個地方:

  • 當動態RAM上電時,單元保持在任意狀態,直到初始化為止; 這是大多數內存硬件實現的屬性
  • 當程序運行時,它會留下以前使用但不再在范圍內的變量值。 此屬性可能用於攻擊:分析程序遺留的垃圾可能會向插件或您使用的其他庫的不道德作者提供信息。

未初始化變量的值是在將相應的內存區域分配給此變量之前存在的值。 大多數情況下,它是不可預測的,並取決於此內存區域之前發生的任何事情。

實際上,這有時用作附加熵來生成偽隨機數。 幾年前,Debian開發人員認為未初始化的變量是OpenSSL中的一個錯誤並將其設置為零。 然后生成的密鑰變得有些猜測,現在每個Debian用戶都必須在他們的機器上安裝一長串黑名單鍵。

簡短的回答? 這取決於你的編譯器 - 但不要這樣做。

答案很長:
訪問未初始化的POD(普通舊數據,如int )類型的值會調用未定義的行為 ,這意味着C標准在這種情況下不會對符合要求的實現提出任何要求。 因此,允許編譯器發出啟動nethack ,格式化硬盤驅動器或根本不執行任何操作的機器代碼,同時仍然符合C標准 - 只要它可以證明程序中的任何位置都發生未定義的行為。

(另請閱讀: 每位C程序員應該了解的未定義行為

那么,實際上(可能)會發生什么?
沒有啟用優化的大多數現代編譯器中,編譯器將簡單地在堆棧(或寄存器)上為變量分配一個槽,然后在被詢問之前訪問該位置處的任何內容。 結果似乎是“隨機記憶”,但實際上它根本不是隨機的

如果我啟用優化會發生什么?
然后,如果您在更高的優化級別上編譯代碼(或者編譯器已更新並且現在更積極地進行優化),則所有投注均已關閉。 例如,編譯器可以刪除任何涉及x調用,將x分配x其他變量相同的位置(認為x不可能被使用,因為它尚未初始化),或任何其他奇怪效果的組合

換句話說,當您訪問該未初始化的變量時,您的程序可以開始執行您無法控制的任何操作。 不要這樣做 - 這里是龍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM