运行'GC.Collect'修复了我的崩溃,但我不明白为什么

Gre*_*reg 1 c# unmanaged nokia

我有这段代码(来自诺基亚PC连接3.2示例代码,在C#中):

  DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo =
  new DAContentAccessDefinitions.CA_FOLDER_INFO();
  folderInfo.iSize = Marshal.SizeOf(folderInfo); //(32)

  IntPtr bufItem = Marshal.AllocHGlobal(folderInfo.iSize);

  //I often get a AccessViolationException on the following line
  Marshal.StructureToPtr(folderInfo, bufItem, true);
Run Code Online (Sandbox Code Playgroud)

如果我GC.Collect()在开始时运行,那么我没有得到AccessViolationException.但除非必要,否则我不想放慢这个功能.我尝试GC.Keepalive过各种各样的地方,但没有成功.

CA_FOLDER_INFO 定义为:

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct CA_FOLDER_INFO
    {
        public int iSize;
        public int iFolderId;
        public int iOptions;
        public string pstrName;
        public string pstrPath;
        public int iSubFolderCount;
        public IntPtr pSubFolders;
        public IntPtr pParent;
    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我不需要任何一个字符串,并且更改它们的定义IntPtr似乎会使异常消失.

这里发生了什么,以及防止异常的正确方法是什么?

小智 5

你的问题是你传递给Marshal.StructureToPtr,所以它试图释放两个字符串指针(有时无效).您需要在此实例中传递false,因为您刚刚在堆上分配了该内存.(即那里没有什么可以自由的).