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

运行“GC”。Collect修复了我的崩溃,但我不明白为什么

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

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

    如果我跑 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 回复  |  直到 12 年前
        1
  •  5
  •   Remi Lemarchand    16 年前

    你的问题是,你正在向元帅传递真实。StructureToPtr,因此它试图释放两个字符串指针(有时无效)。在这种情况下,您需要传递false,因为您刚刚在堆上分配了内存。(也就是说,那里没有什么可以释放的)。

        2
  •  0
  •   scottm    16 年前

    你确定吗,元帅。尺寸(bufItem)和元帅。大小(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 icecrime    12 年前

    使用固定关键字获取指向原始关键字的指针 folderInfo .

        4
  •  0
  •   Peter Mortensen icecrime    12 年前

    可能是某些东西没有释放非托管资源。检查您是否使用了任何工具 IDisposable 如果是这样,把它包起来 using { } 块。