簡體   English   中英

如果不在C程序中調用fclose()會發生什么?

[英]What happens if I don't call fclose() in a C program?

首先,我知道用fopen()打開文件而不關閉文件是非常不負責任的,而且格式不好。 這只是純粹的好奇心,所以請逗我:)

我知道,如果C程序打開一堆文件並且從不關閉任何文件,最終fopen()將開始失敗。 還有其他副作用可能導致代碼本身之外的問題嗎? 例如,如果我有一個程序可以打開一個文件,然后退出而不關閉它,那可能會對運行該程序的人造成問題嗎? 這樣的程序會泄漏任何東西(內存,文件句柄)嗎? 程序完成后,再次訪問該文件是否會出現問題? 如果該程序連續運行多次會發生什么?

只要您的程序正在運行,如果您繼續打開文件而不關閉它們,最有可能的結果是您將用完進程可用的文件描述符/句柄,並且嘗試打開更多文件最終將失敗。 在Windows上,這還可以防止其他進程打開或刪除您已打開的文件,因為默認情況下,文件以獨占共享模式打開,從而阻止其他進程打開它們。

程序退出后,操作系統將在您執行后清理。 它將在終止過程時關閉您打開的所有文件,並執行其他必要的清除操作(例如,如果將文件標記為“關閉時刪除”,則它將刪除該文件;請注意,這種事情是平台的) -具體)。

但是,要注意的另一個問題是緩沖數據 大多數文件流在將數據寫到磁盤之前都會在內存中緩沖數據。 如果您正在使用來自stdio庫的FILE*流,則有兩種可能性:

  1. 通過調用exit(3)函數或從main返回(隱式調用exit(3) ),程序可以正常exit(3)
  2. 您的程序異常退出; 這可以通過調用abort(3)_Exit(3) ,死於信號/異常等來實現。

如果您的程序正常退出,則C運行時將負責刷新所有打開的緩沖流。 因此,如果您緩沖的數據寫入了未刷新的FILE* ,它將在正常退出時被刷新。

相反,如果程序異常退出,則不會刷新任何緩沖的數據。 進程終止時,操作系統只是說“哦,親愛的,您打開了文件描述符,我最好為您關閉文件描述符”。 它不知道程序中有一些隨機數據位於內存中某個位置,而程序打算將其寫入磁盤。 因此,請注意這一點。

C標准說,調用exit (或等效地從main返回)會導致所有打開的FILE對象被fclose視情況關閉。 因此,這很好,只不過您放棄了檢測寫錯誤的機會。

編輯:對於異常終止,沒有這樣的保證( abort ,失敗的assert ,收到其默認行為是異常終止程序的信號-請注意,不一定有任何此類信號-以及其他實現定義的方法)。 正如其他人所說,現代操作系統將清除所有外部可見資源,例如開放OS級別的文件句柄。 但是,在這種情況下,很可能不會刷新FILE

當然,有些操作系統在異常終止時不會清除外部可見的資源。 它往往與不執行“核心”和“用戶”的代碼和/或之間存在明顯的用戶空間“進程”之間的硬邊界特權一起去,只是因為如果你沒有這些邊界也未必這樣做安全在所有情況下。 (例如,考慮到如果您完全有能力在MS-DOS中的打開文件表上寫入垃圾,會發生什么情況。)

假設您在控制之下退出,使用exit()系統調用或從main()返回,則刷新后關閉打開的文件流。 C標准(和POSIX)強制執行此操作。

如果退出控制(核心轉儲,SIGKILL)等,或者使用_exit()_Exit() ,則打開的文件流不會被刷新(但是文件描述符最終會關閉,假設是類似POSIX的系統文件描述符-標准C不強制使用文件描述符)。 請注意, _Exit()由C99標准規定,但_exit()由POSIX規定(但它們在POSIX系統上的行為相同)。 請注意,文件描述符與文件流是分開的。 請參閱POSIX頁面上有關_exit()的“程序終止的后果”的討論,以了解當程序在Unix下終止時會發生什么。

當進程終止時,大多數現代操作系統(特別是內核)將釋放所有句柄和分配的內存。

暫無
暫無

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

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