Unity C#中如何通过intPtr编写for循环遍历float类型数组?
问题核心错误点
- 你将
IntPtr类型的内存地址直接赋值给int类型循环变量,64位运行环境下IntPtr为8字节长度,直接转为int会出现地址截断,访问非法内存直接触发崩溃。 - 你把字节偏移量直接当作数组下标使用,
presumedToBeAnArrayLocation[i]中的下标i是按元素个数计数,不是按字节计数,步长加4相当于每次跳过4个float元素,完全不符合你偏移4字节的预期,且截断后的地址数值极大,直接触发数组越界崩溃。
正确解决方法
分两种常用实现方案:
方案1:unsafe指针操作(需在Unity Player Settings中勾选Allow 'unsafe' Code)
unsafe { float myFloatVar = 42.42f; // 将IntPtr转为float指针,指针步长自动适配float的4字节长度 float* floatArrayPtr = (float*)varIntPtr; // 12字节总长度对应3个float元素,按元素个数遍历即可 for (int i = 0; i < 3; i++) { floatArrayPtr[i] = myFloatVar * i; } }
方案2:Marshal类操作(无需启用unsafe代码)
float myFloatVar = 42.42f; for (int i = 0; i < 3; i++) { // 计算当前元素的内存地址:起始地址 + 字节偏移(元素索引*4) IntPtr currentAddr = varIntPtr + i * 4; System.Runtime.InteropServices.Marshal.StructureToPtr(myFloatVar * i, currentAddr, false); }
额外注意事项
- 如果你操作的是Unity托管的float数组,直接取地址操作前必须用
fixed语句固定数组内存,否则GC移动数组内存后你持有的地址会变成野指针,同样会触发崩溃。 - 遍历长度必须提前确认准确,内存越界要么直接崩溃要么触发无规律的数值异常,排查成本极高。
内容的提问来源于stack exchange,提问作者Confused
相关产品推荐
相关产品推荐

