集合表达式中展开已初始化的inline array触发AccessViolationException
Inline Array 使用 Spread Element 触发访问违规异常的问题
这是一个已知问题(编号#70708):当通过包含数组元素赋值逻辑的构造函数创建inline array时,直接对该inline array使用spread element语法会抛出System.AccessViolationException。
问题复现代码
定义如下inline array结构:
[InlineArray(8)] public struct InlineIntArray8 { private int element0; public InlineIntArray8() { for (int i = 0; i < 8; ++i) { this[i] = i; } } }
通过以下代码访问时,最后一行会触发异常:
InlineIntArray8 inlineArray = new(); ReadOnlySpan<int> readOnlySpanFromMemoryMarshal = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<InlineIntArray8, int>(ref inlineArray), 8); ReadOnlySpan<int> readOnlySpanFromImplicitConversion = inlineArray; ReadOnlySpan<int> readOnlySpanWithSpreadElementFromExistingReadOnlySpan = [42, ..readOnlySpanFromImplicitConversion]; ReadOnlySpan<int> readOnlySpanFromSpreadElement = [5, ..inlineArray]; // AccessViolationException
异常触发的边界情况
- 除直接对inline array使用spread element的方式外,其余创建
ReadOnlySpan<int>的方法均正常工作 - 对inline array隐式转换得到的
ReadOnlySpan<int>使用spread element不会抛出异常 - 移除构造函数中的元素赋值逻辑(即删除
this[i] = ...代码)后,使用spread element不会触发异常
异常原因分析
该问题是Roslyn编译器的实现缺陷:当构造函数中对inline array的元素进行赋值后,编译器生成的spread element处理代码未能正确识别inline array的内存布局,错误地访问了非法内存区域。具体来说,编译器在处理直接针对inline array的spread操作时,没有正确处理构造函数修改元素后的内存状态,导致内存访问越界或引用无效内存,最终触发System.AccessViolationException。
内容的提问来源于stack exchange,提问作者monkey0506
相关产品推荐
相关产品推荐

