2012-03-27 90 views
1

我在我的应用程序中使用Trhird派对工具。在某些系统上,我收到System.AccessViolation错误。尽管通过代码我无法再现问题。但在生产环境中,它确实会在某个时间重现。System.AccessViolation由于Marshal.StructureToPtr

我有下面的代码

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; 
} 
+0

如果您提供“true”而不是false,会发生什么情况? – Aliostad 2012-03-27 13:27:41

+0

显然你必须通过false,因为没有旧的结构要删除。 – 2012-03-27 23:13:31

+0

你的应用程序的目标是什么?我希望它是x86给予ToInt32。 – 2012-03-27 23:14:52

回答

3

不是一个真正的答案一样多一些观察,但它得到了太长的评论,所以:

  1. 如果您想要返回代表nullIntPtr,使用IntPtr.Zero;这是它的全部目的。

  2. IntPtr类有一个Add方法,该方法为现有的IntPtr添加一个偏移量,该偏移量比您所做的更安全。

  3. 由于您刚刚分配了您的全局缓冲区,并且它没有可管理的参考,所以您应该继续通过falseStructureToPtr;有什么好说的了自由,在任何情况下

你能告诉正是此代码的行生产的访问冲突?

+0

感谢迈克尔你有价值的投入..记录显示消息,直到for循环(例如为( var index = 0; index 2012-03-28 05:39:18

+0

In。NET 4中,只有指示它们可以处理损坏的状态异常的方法才能获得它们;如果在调用堆栈的中间层中有这样的方法,则无论实际抛出的内容有多深,它都会显示为抛出异常。您可以使用传统的损坏状态异常策略来关闭此行为,这可能会帮助您调试您的问题:http://msdn.microsoft.com/zh-cn/library/dd638517.aspx – 2012-03-29 14:31:59

0

你在64位运行疑问?当然,下面的代码将失败:buffer.ToInt32()

在完成缓冲区之后,您还应该调用FreeHGlobal。将参数保留为false

2

我不知道是什么原因造成的访问冲突,但此行:

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)); 
} 
+0

感谢里奇和迈克尔您的宝贵意见,我一定会尝试这一点,但我无法重现它调试模式,所以需要在生产环境中检查它与这些更改...我已经使用HandleProcessCorruptedStateExceptions来捕获异常...对此有何评论? – 2012-03-28 05:35:30

+0

我正在Marshlling的结构是这样的:[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi)] 公共结构MyStructure – 2012-03-28 05:45:49