非托管Bag返回错误值:对齐偏移计算疑存异常
问题定位与修复
你的非托管Bag容器中,Get
错误原因分析
UnsafeUtility.ReadArrayElementWithStride<T>的参数逻辑和你当前的使用场景完全不匹配:
- 第二个参数是数组元素的索引,不是字节偏移量
- 第三个参数是数组中每个元素之间的字节步长
你在代码中把elementOffset(字节偏移量)当作索引传入,导致实际读取的内存位置完全偏离目标区域。比如读取int元素时,传入偏移量4,该方法会计算为ptr + 4 * sizeof(int),也就是从第16字节开始读取,而非预期的第4字节,自然得到错误值。而float和bool刚好因为参数巧合(float的偏移量0对应索引0,bool的偏移量8对应步长1时的索引8)暂时表现正常,但这种行为完全不可靠。
修复后的Get方法
将Get方法替换为直接通过指针偏移读取结构的实现(二选一即可):
方式1:使用UnsafeUtility.ReadUnaligned
public unsafe T Get<T>(int index) where T : unmanaged { int elementOffset = offsets[index]; byte* ptr = data.GetUnsafeReadOnlyPtr(); // 将指针偏移到目标位置后读取结构 return UnsafeUtility.ReadUnaligned<T>(ptr + elementOffset); }
方式2:直接指针转换(因已做对齐,无需Unaligned)
public unsafe T Get<T>(int index) where T : unmanaged { int elementOffset = offsets[index]; byte* ptr = data.GetUnsafeReadOnlyPtr(); return *(T*)(ptr + elementOffset); }
额外验证
你的内存对齐逻辑AlignOffset是正确的,确保了每个元素的内存地址符合其类型的对齐要求;Set方法的实现也没有问题,直接通过指针偏移写入结构的逻辑是正确的。
修复后重新运行测试代码,int类型的读取和更新就能得到正确结果。
内容的提问来源于stack exchange,提问作者UnknownUser
相关产品推荐
相关产品推荐

