为什么我得到System.OutOfMemoryException?

时间:2011-05-18 19:19:37

标签: c#

我在c#中有以下代码段。

 var list = new List<string> { "a", "b", "c" };
            for (int i = 0; i < list.Count; i++)
            {
                list.Add(list[i].ToUpper());
            }

上面的代码中没有编译时错误,但我在运行时遇到System.OutOfMemoryException异常?

9 个答案:

答案 0 :(得分:10)

每次添加元素时,

List.Count都会重新评估。

所以,你有3个元素。在for循环的第一次迭代之后,您将Count == 4.因此i永远不会达到Count值(直到整数溢出情况,但在您的情况下,内存不足)

你可以写smth。像:

var listInUpperCase = list.Select(x => x.ToUpper())
                          .ToList();

list.AddRange(listInUpperCase);

答案 1 :(得分:4)

循环的每次迭代都会添加一个项目。循环的上限(list.Count)增加。你继续循环。最终,你的内存不足。

要解决您的问题,请事先获取计数。

int count = list.Count;
for (int i = 0; i < count; i++)
{

答案 2 :(得分:2)

在每次迭代时评估循环条件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"}

答案 3 :(得分:1)

你的循环永远不会结束,因为Count是通过循环每次迭代计算的,并且你在循环中每次迭代都会增加Count。由于我从0开始,你将无限期地添加项目,直到你的内存不足为止。

答案 4 :(得分:1)

看起来你在列表中添加了一个新项目,因此无论整数的最大值是什么,我都不会达到列表计数和最大值。

答案 5 :(得分:1)

这是一个无限循环。您将继续永久地向列表中添加元素。 i从0开始,列表以3个元素开头。每次迭代中每个都增加1,因此i永远不会赶上。当列表不可避免地消耗所有可用内存时,就会发生异常。

答案 6 :(得分:1)

您正在将列表循环到最后,同时向其中添加项目。所以永远不会达到目的。我想你的意思是:

var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
    list[i] = list[i].ToUpper();
}

答案 7 :(得分:1)

因为for循环在i < list.Count期间继续发生,因为你在每次迭代中都添加了一个新项目。使用另一个列表作为大写字符串,或者在开始循环之前计算一次:

int length = list.Count;
for (int i=0; i<length; i++)
...

答案 8 :(得分:1)

因为你正在改变循环体中的计数器值!它永远不会结束。

var list = new List<string> { "a", "b", "c" };
for (int i = 0; i < list.Count; i++)
{
    list[i] = list[i].ToUpper();
}