2013-10-17 62 views
2

在Windows上無效的虛擬內存,我注意到,試圖取消引用指針最近釋放的內存會導致系統崩潰,由Visual Studio指出,內存是無效被困。這是預期的。然而,執行相同的應用程序和代碼路徑導致取消引用最近釋放的內存的指針不會立即導致Linux崩潰。這表明Linux內核(或GNU C++運行時)不會非常快速地使釋放的內存失效,即使在調試版本上也是如此。應用程序需要更長的時間才能崩潰。是這樣嗎?如果是這樣,我可以強制內存更快地取消映射嗎?如果不是,那麼發生了什麼?是否有可能迫使Linux之後免費

+0

我不知道。無論什麼時候出現,我都會停止做UB,而不是試圖瞭解到底發生了什麼。 –

回答

2

你試過http://valgrind.org/?目的是幫助追蹤諸如您所描述的問題。

+0

+1; Valgrind真棒。可能很複雜,但它是一個很好的工具。 – thirtythreeforty

+0

是的,我正在使用Valrgind。 memcheck工具清楚地報告從無效內存讀取。我只是對Windows和Linux釋放內存之間的明顯差異感到好奇。 – user1332148

+0

那麼,AFAIK行爲沒有定義,所以難怪它在不同的系統(甚至編譯器,編譯器版本,編譯器選項)上有所不同。 – domen

2

大多數new/delete實現不立即返回內存 到系統中,或者至少不回小 塊。我很驚訝你的代碼在 Windows下崩潰,只需通過取消引用指向內存的指針;你是否確實沒有做過多的事情(例如,使用你通過指針讀取的值 )。

有多大,塊?許多實現策略根據塊的大小使用不同的策略,並立即釋放非常大的塊。 (IIRC,Linux會做一個mmap 立即非常大的塊,並立即取消映射它,當 你釋放它。當然,如果你重新分配之間的內存 自由和非關聯化的指針,它有可能是 地址是在新分配的空間,它不會崩潰)

到底:映射的粒度頁面,您 不能指望分配器阻止了一個完整的頁面每個 分配,只是使其可以在釋放後立即使存儲器 無效。 (一個頁面可能至少爲4K, ,並且您不希望每次分配16個字節時都會釋放4K地址空間。)跟蹤所有內存訪問(如 ValGrand或Purify)並且運行速度較慢,唯一 替代方案是使用垃圾收集,以確保 存儲器沒有限制,只要有一個指向它的指針, 重新分配的和完全覆蓋它上釋放(即,在deletefree)與可能的值如果使用 (0xDEADBEEF或類似的東西)會導致問題。即使如此,你是 不能保證你會崩潰— 0xDEADBEEF可能 是你認爲你正在閱讀的有效值。 (但是,這 確實允許例如設置標誌;在構造函數中,在析構函數將其復位 ,並在每個功能測試它。對於具有積極的防守代碼 。)

相關問題