我在我的应用程序中使用Trhird派对工具。在某些系统上,我收到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;
}
答案 0 :(得分:3)
并不像一些观察结果那么真实,但是评论太长了,所以:
如果您想返回代表IntPtr
的{{1}},请使用null
;这就是它的全部目的。
IntPtr.Zero
类有一个IntPtr
方法,可以为现有的Add
添加偏移量,这比您正在做的更安全。
由于您刚刚分配了全局缓冲区,并且尚未包含托管引用,因此您应该继续将IntPtr
传递给false
;无论如何,没有任何东西可以免费
您能准确说出此代码的哪一行产生访问冲突吗?
答案 1 :(得分: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));
}
答案 2 :(得分:0)
你在64位上运行吗?当然,以下代码将失败:buffer.ToInt32()
完成缓冲后,您还应该调用FreeHGlobal。将参数保留为false
。