C#中如何定位‘Attempted to read or write protected memory’错误根源
调试C#中"Attempted to read or write protected memory"错误的方法
启用非托管代码调试
打开Visual Studio项目属性,找到「调试」选项卡,勾选「启用非托管代码调试」。这类错误大多是托管代码调用非托管代码时内存操作出问题,开启非托管调试后,能捕获到完整的跨语言调用栈,直接定位到非托管侧的出错函数。逐一核对P/Invoke与COM互操作代码
这个错误90%以上和非托管互操作有关,重点检查:- 函数签名是否和非托管DLL完全匹配(返回值、参数类型、调用约定都不能错)
- 内存分配与释放逻辑是否正确:比如托管端传给非托管的对象,有没有提前被GC回收;非托管返回的内存块,有没有在托管端正确释放
- 字符串、数组的封送是否正确,必要时用
[MarshalAs]特性指定明确的封送规则
切换到本机调用栈查看
错误触发时,在调试窗口的「调用栈」面板里,点击「显示外部代码」,然后切换到「本机调用栈」(开启非托管调试后才会显示)。这里能看到非托管层面最后执行的函数,直接锁定问题根源。用内存检测工具深挖
- 用Visual Studio自带的「内存诊断」:调试会话中,点「调试」→「内存诊断」,捕获内存快照后分析是否有泄漏或越界访问
- 用WinDbg分析dump文件:错误发生时生成dump,加载后执行
!analyze -v命令,工具会直接给出内存损坏的原因和关联函数
排查unsafe代码块
如果项目里有unsafe代码(直接操作指针),逐行检查:- 有没有数组越界访问
- 有没有访问已被释放的内存
- 指针偏移量计算是否正确
分步隔离测试
逐步禁用或注释掉可疑模块——尤其是涉及非托管调用、大量内存操作的部分,每次改完运行程序,直到错误消失,就能锁定问题模块,再深入排查具体函数。
内容的提问来源于stack exchange,提问作者Mich
相关产品推荐
相关产品推荐

