为什么我得到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异常?

为什么我得到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();
}