簡體   English   中英

由於Marshal.StructureToPtr而導致的System.AccessViolation

[英]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;
}

回答不完全是一些觀察,但是評論太長,所以:

  1. 如果要返回表示nullIntPtr ,請使用IntPtr.Zero ; 這就是它的全部目的。

  2. IntPtr類具有一個Add方法,該方法將偏移量添加到現有IntPtr ,這比您正在做的事更安全。

  3. 由於您剛剛分配了全局緩沖區,並且還沒有托管引用,因此您應該繼續將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.

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