C#值传递与引用传递疑问:System.OverflowException异常排查
解决System.OverflowException与C#值/引用传递的误区
C#与Java的对象传递逻辑对比
- Java里所有参数都是值传递:对象类型传递的是引用的副本(栈中存储堆地址的拷贝),这和C#中引用类型(class)的默认传递逻辑完全一致。
- C#里的引用类型默认也是值传递(传递引用的副本),副本指向的是同一个堆对象,和Java没有本质区别。只有当需要让方法修改原引用本身时,才需要用
ref或out关键字。你当前的useSummary方法参数传递逻辑没有问题,不是导致溢出的原因。
定位System.OverflowException的真实原因
错误明确触发在IntPtr basePointer = (IntPtr) summary.MainModuleBase;这一行,核心是数值类型转换时的范围溢出:
- 32位进程中,
IntPtr是4字节,最大值为0x7FFFFFFF(约2GB),如果summary.MainModuleBase存储的是64位进程的模块基地址(通常超过2GB),强制转换为32位IntPtr就会触发溢出。 - 即使是64位进程,如果
MainModuleBase是负数或超出IntPtr合法范围的数值,也会引发该错误。
具体解决方案
调整项目平台目标:
如果你的程序是32位编译,但目标处理的是64位进程,直接将项目的平台目标改为x64,或者设为Any CPU并取消勾选“首选32位”选项,这样IntPtr会适配64位地址范围。安全转换数值到IntPtr:
避免直接强制转换,先做范围检查再转换:public bool useSummary(Summary summary, out PEFile outputFile) { outputFile = default(PEFile); // 检查当前进程位数与地址范围的兼容性 if (IntPtr.Size == 4 && summary.MainModuleBase > int.MaxValue) { // 处理32位进程无法访问64位地址的场景,比如返回错误提示 return false; } IntPtr basePointer = new IntPtr(summary.MainModuleBase); IMAGE_DOS_HEADER dosHeader = ReadProcessStruct<IMAGE_DOS_HEADER>(summary.ProcessId, basePointer); // 后续逻辑 return true; }确认MainModuleBase的类型定义:
检查Summary类中MainModuleBase的类型,如果是ulong(无符号64位整数),在32位环境下需要确保其值不超过int.MaxValue,否则必须切换到64位平台运行。
内容的提问来源于stack exchange,提问作者UnSure
相关产品推荐
相关产品推荐

