[英]System.AccessViolation due to Marshal.StructureToPtr
我在我的應用程序中使用了Trhird party工具。 在某些系統上,我收到System.AccessViolation錯誤。 雖然通過代碼我無法重現該問題。 但是在生產環境中,它確實會在某些時候復制。
我對以下代碼有疑問
public static IntPtr TestMarshalToPointer(object value, System.Type type, int length)
{
int offset = 0;
int size = Marshal.SizeOf(type) * length;
IntPtr buffer;
try
{
buffer = Marshal.AllocHGlobal(size);
for (var index = 0; index < length; index++)
{
Marshal.StructureToPtr(value, new IntPtr(buffer.ToInt32() + offset), false);
// Its written on MSDN that passing false can lead to memory leak. Please guide , should i need to pass true and how it will affect**
offset += Marshal.SizeOf(type);
}
}
catch
{
buffer = (IntPtr)null;
}
return buffer;
}
回答不完全是一些觀察,但是評論太長,所以:
如果要返回表示null
的IntPtr
,請使用IntPtr.Zero
; 這就是它的全部目的。
IntPtr
類具有一個Add
方法,該方法將偏移量添加到現有IntPtr
,這比您正在做的事更安全。
由於您剛剛分配了全局緩沖區,並且還沒有托管引用,因此您應該繼續將false
傳遞給StructureToPtr
; 在任何情況下都沒有免費的東西
您能否確切說明此代碼的哪一行產生訪問沖突?
我不確定是什么原因導致了訪問沖突,但是這一行:
Marshal.StructureToPtr(value, new IntPtr(buffer.ToInt32() + offset), false);
似乎可疑。 通過更聰明地使用IntPtr
類來替換代碼可能會有所幫助:
buffer = Marshal.AllocHGlobal(size);
offset = buffer;
for (var index = 0; index < length; index++)
{
Marshal.StructureToPtr(value, offset, false);
IntPtr.Add(offset, Marshal.SizeOf(type));
}
您在64位上運行嗎? 當然,以下代碼將失敗: buffer.ToInt32()
完成緩沖區后,還應該調用FreeHGlobal。 將參數保留為false
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.