我正在處理一些C#和C++非託管代碼,並且在處理內存時存在兩個不明白的地方。如果有人能幫助我理解:使用C#和C++非託管時的內存分配/取消分配
如果一個變量在C#下動態分配(使用new),然後傳遞給C++非託管代碼。該變量內存是否需要在用戶的C++非託管代碼下手動釋放?
如果一個變量在C++非託管(使用new)的情況下動態分配,然後傳遞給C#,可以安全地說垃圾收集器會釋放該內存嗎?
我正在處理一些C#和C++非託管代碼,並且在處理內存時存在兩個不明白的地方。如果有人能幫助我理解:使用C#和C++非託管時的內存分配/取消分配
如果一個變量在C#下動態分配(使用new),然後傳遞給C++非託管代碼。該變量內存是否需要在用戶的C++非託管代碼下手動釋放?
如果一個變量在C++非託管(使用new)的情況下動態分配,然後傳遞給C#,可以安全地說垃圾收集器會釋放該內存嗎?
這真的很簡單!
嗯,我們對此深感抱歉。
byte[]
)。當傳遞給非託管代碼的對象/指針的生命週期應該比被調用方法的運行時間長時,請勿使用自動編組。這當然只適用於指針。傳遞整數是非常好的,使用自動編組通常意味着編組負責處理大部分細節(雖然仍然只在最簡單的情況下,所以要小心)。非託管代碼是非託管 - 您需要完全理解內存如何分配以及如何,何時以及由誰負責清理內存。
作爲一個經驗法則,無論component
/object
分配的內存應該釋放內存。每做new
a delete
由做new
。
這是理想的。如果由於諸如您的原因而沒有遵循C++
程序可能會終止並且在分配內存的生命週期結束時不存在,則您的C#
應該清理,反之亦然。
不,因爲對象在託管堆上分配GC將像往常一樣處理重新分配。問題是你必須告訴他不要從非託管代碼中釋放或更改對象的地址,因爲GC無法知道從非託管代碼中使用對象的時間。這可以通過釘住對象來完成。 查看this的問題。
不,因爲對象在C++非託管堆上分配GC不會觸及它。你必須使用delete自己釋放它。
編輯: 如果您需要在非託管代碼中,反之亦然託管代碼和釋放分配一個對象,這是很好的知道有這個目的,你可以通過從Marshal.AllocHGlobal和Marshal.FreeHGlobal呼叫使用OS堆C#在C++中會有類似的調用。
>互操作中的常見錯誤是內存在非託管側完成之前解除分配。 請參閱https://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx – Wollmich