我借用别人的代码,5秒循环读取其它程序内存数据,程序运行后5分钟左右死了,提示尝试读取或写入受保护的内存,这通常指示其他内存已损坏,我加了两句代码for和buffer = null;后,程序多运行了15分钟,还是死了,提示相同错误,请问如何改?从其它程序读取内存数据有的代码如下:  public static int ReadMemoryValue(int baseAddress, string processName)
        {
            try
            {
                byte[] buffer = new byte[4];
                IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //获取缓冲区地址
                IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
                ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //将制定内存中的值读入缓冲区
                CloseHandle(hProcess);                for (int i = 0; i < buffer.Length; i++)
                    buffer[i] = 0;//我自已加的代码                buffer = null;//我自已加的代码                return Marshal.ReadInt32(byteAddress);//在运行时提示在运行时提示尝试读取或写入受保护的内存,这通常指示其他内存已损坏。。
              
            }
            catch
            {
                return 0;
            }
        }

解决方案 »

  1.   

            public static extern IntPtr OpenProcess
                (
                    int dwDesiredAccess,
                    bool bInheritHandle,
                    int dwProcessId
                );        public static void WriteMemoryValue(int baseAddress, string processName, int value)
            {
                IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高权限
                WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, 4, IntPtr.Zero);
                CloseHandle(hProcess);
            }
    借用的源码地址http://www.cnblogs.com/gleamy_ming/archive/2011/03/16/1985656.html
      

  2.   

    CloseHandle(hProcess);
    这里不是已经将资源回收了么?你在读取byteAddress自然不对了 把CloseHandle(hProcess);
    放在代码的最后。
      

  3.   

    "5秒循环读取"是什么意思,你代码里好像看不到。
    Marshal.UnsafeAddrOfPinnedArrayElement这个方法是获得托管内存块地址,托管内存地址会被GC移动,就有可能在被移动后,IntPtr byteAddress不再指向buffer。
    你需要在调用Marshal.UnsafeAddrOfPinnedArrayElement前通过GcHandle将buffer固定,然后再循环操作。或者使用Marshal.AllocCoTaskMem在非托管内存分配四个字节,这样不会被GC移动,完事后调用Marshal.FreeCoTaskMem释放该非托管内存。
      

  4.   

    垃圾一般在C# 环境下 不用管
    自己会释放的可以用System.GC.Collect();  强制释放
      

  5.   

    ReadProcessMemory() 应该是这个方法内有问题...
    读取内存时有个释放的方法 flush() 你看看用没用...
    一定要读一段就要释放一段...
      

  6.   

    垃圾一般在C# 环境下 不用管
    自己会释放的可以用System.GC.Collect(); 强制释放
      

  7.   

    将你加的两句删除,改为:
    CloseHandle(hProcess);GC.KeepAlive(buffer);//让内存不被回收return Marshal.ReadInt32(byteAddress);
    这样可能行