代码之家  ›  专栏  ›  技术社区  ›  Greg

运行“gc.collect”修复了我的崩溃,但我不明白为什么

  •  1
  • Greg  · 技术社区  · 15 年前

    我有这段代码(来自诺基亚PC Connectivity 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);
    

    如果我跑 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;
        }
    

    在本例中,我不需要任何一个字符串,并将它们的定义更改为 IntPtr 似乎让这个例外消失了。

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

    4 回复  |  直到 15 年前
        1
  •  5
  •   Remi Lemarchand    15 年前

    您的问题是,您正在将true传递给marshal.structureToptr,以便它尝试释放两个字符串指针(有时这两个指针无效)。您需要在这个实例中传递false,因为您刚刚在堆上分配了内存。(也就是说,那里没有空余的东西)。

        2
  •  0
  •   scottm    15 年前

    你确定marshal.sizeof(bufitem)和marshal.sizeof(folderinfo)是相同的吗?

    也许你没有初始化字符串?既然您说在intptr(默认为intptr.zero)时不会得到错误,那么在尝试封送缓冲区项之前,我会尝试将两者都设置为空字符串。

    [编辑]

    也许您应该尝试固定缓冲区句柄,并将其封送到结构中,而不是相反。像这样:

    DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
    
    GCHandle pinnedHandle = GCHandle.Alloc(buffItem, GCHandleType.Pinned);
    folderInfo = (DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(DAContentAccessDefinitions.CA_FOLDER_INFO));
    pin.Free();
    
    //folderInfo should contain the data from buffItem
    
        3
  •  0
  •   Peter Mortensen Sumit Kumar    11 年前

    使用fixed关键字获取指向原始文件的指针 folderInfo .

        4
  •  0
  •   Peter Mortensen Sumit Kumar    11 年前

    可能是非托管资源没有被某些东西释放。检查你使用的工具 IDisposable 如果是这样,用 using { } 块。