C#错误声明多维数组引发OutOfMemoryException的原因与解决
为什么
new char['a', 'e', 'i', 'o', 'u']会触发OutOfMemoryException,以及预防方案 问题根源:两种数组声明的语法差异
你写的第一行代码new char['a', 'e', 'i', 'o', 'u'],根本不是创建包含5个元音的一维数组——它是在声明一个5维数组,每个维度的长度由传入字符对应的ASCII值决定:
'a'的ASCII值为97,第一维长度是97'e'的ASCII值为101,第二维长度是101'i'的ASCII值为105,第三维长度是105'o'的ASCII值为111,第四维长度是111'u'的ASCII值为117,第五维长度是117
这个数组的总元素数量是97 * 101 * 105 * 111 * 117,约12.5亿个char元素,每个char占2字节,总内存需求超过25GB,远远超出程序能分配的内存上限,运行时必然抛出OutOfMemoryException。
而第二行代码new char[] { 'a', 'e', 'i', 'o', 'u' }是正确的一维数组初始化语法:char[]明确指定一维数组类型,{ ... }是元素初始化器,只会创建包含5个char元素的小数组,自然能正常运行。
编译通过的原因
C#允许char隐式转换为int,而多维数组的维度长度要求是int类型的常量表达式。编译器会自动把每个字符转换成对应的ASCII整数当作维度长度,语法上完全合法,所以不会报错——但这是典型的逻辑错误,编译器无法预判你真实的意图是创建多维数组还是一维数组。
最佳预防方法
- 严格区分数组声明语法:
- 一维数组初始化用
new char[] { 元素1, 元素2, ... }(可以省略char[]让var推断,但保留类型声明更清晰) - 多维数组声明用
new char[维度1长度, 维度2长度, ...],维度长度必须是合理的整数,不要用字符这类容易混淆的类型
- 一维数组初始化用
- 启用并重视编译器警告:
把C#项目的警告级别设为Level 4,编译器会对char隐式转int的操作发出警告(CS0642),及时提醒你可能存在逻辑错误 - 避免模糊的语法写法:
不要依赖隐式转换编写维度长度,尽量显式使用整数;如果是创建包含字符元素的数组,务必用{ ... }初始化器,不要把元素放在[]内
内容的提问来源于stack exchange,提问作者Makusium
相关产品推荐
相关产品推荐

