为什么我得到System.OutOfMemoryException
本文关键字:System OutOfMemoryException 为什么 | 更新日期: 2023-09-27 17:56:45
我在 c# 中有以下代码片段。
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list.Add(list[i].ToUpper());
}
上面的代码中没有编译时错误,但我在运行时遇到System.OutOfMemoryException
异常?
List.Count
每次添加元素时都会重新计算。
所以,你有3个元素。在 for 循环的第一次迭代之后,您将得到 Count
== 4。因此,i
永远不会达到Count
值(直到整数溢出情况,但在您的情况下内存不足发生较早)。
你可以这样写:
var listInUpperCase = list.Select(x => x.ToUpper())
.ToList();
list.AddRange(listInUpperCase);
循环的每次迭代都会添加一个项。循环的上限(list.Count
)增加。你一直在循环。最终,您的内存不足。
要解决您的问题,请事先获取计数。
int count = list.Count;
for (int i = 0; i < count; i++)
{
每次迭代时计算循环条件list.Count
。由于它每次迭代都会增长一个(您将一个元素添加到该列表中),因此您的代码将无休止地循环,直到最终耗尽内存。
如果要将每个元素替换为其大写等效元素,可以使用以下代码:
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list[i]=list[i].ToUpper();
}
// list contains {"A", "B", "C"}
如果你真的想添加到列表中,你可以将计数存储在局部变量中:
var list = new List<string> { "a", "b", "c" };
int count=list.Count;
for (int i = 0; i < count; i++)
{
list[i]=list[i].ToUpper();
}
// list contains {"a", "b", "c", "A", "B", "C"}
您的循环永远不会结束,因为 Count 是通过循环的每次迭代计算的,并且您每次通过循环迭代都会将 Count 增加 1。由于我从 0 开始,您将无限期地添加项目,直到内存不足。
看起来您在列表中添加了一个新项目,因此无论整数的最大值是多少,我都不会达到列表计数和最大值。
无限循环。 您永远向列表中添加元素。 i
从 0 开始,列表从 3 个元素开始。 每个在每次迭代中都增加 1,因此i
永远赶不上。 当列表不可避免地消耗所有可用内存时,会发生异常。
列表中添加项目时将列表循环到最后。因此,这一目的将永远达不到。我想你的意思是:
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list[i] = list[i].ToUpper();
}
因为 for 循环继续,而i < list.Count
永远不会发生,因为您在每次迭代中都会添加一个新项。对大写字符串使用另一个列表,或者在开始循环之前进行一次计数:
int length = list.Count;
for (int i=0; i<length; i++)
...
因为你正在改变循环体中的计数器值! 它永远不会结束。
var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
list[i] = list[i].ToUpper();
}