代码之家  ›  专栏  ›  技术社区  ›  Thorin Oakenshield

在C中使用子字符串方法时引发内存不足异常#

  •  0
  • Thorin Oakenshield  · 技术社区  · 14 年前

    我有一个字符串(字符串)的长度为9700000(约)。和一个for循环从这个字符串中获取子字符串

    喜欢

    for(int i=0;i<MyString.Length;i+=1000)
      {
        String SStr=MyString.Substring(i,1000);
      }
    

    在这个循环中,我得到一个异常,比如 OutOfMemory Exception . 但是如果我把 MyString 到一个临时字符串并使用它( temporary string )而不是 MyString公司 在for循环中,则其工作正常。 为什么会这样。它是如何储存在记忆中的呢?

    编辑 :我用过 StringBuilder

    就像

    for(int i=0;i<MyStringBuilder.Length;i+=1000)
       {
        String SStr=MyStringBuilder.ToString().Substring(i,1000);
       }
    

    但同样的事情正在发生。

    编辑 MyString和MyStringBuilder是全局变量

    2 回复  |  直到 14 年前
        1
  •  1
  •   Will Dean    14 年前

    看起来MyString可能是一个属性,它本身会在每次调用时创建一个新字符串。

    您的800个子字符串调用将使用大约2 MB的内存,这不太可能是问题所在,但是如果您对MyString的800个调用都分配了9.7 MB字符串的新副本,那么这将是一个问题。

    编辑:

    回答这个问题是一个移动的目标,因为您一直在更改它,但是您的新StringBuilder示例在循环中每次都调用ToString,这将生成原始字符串的另一个副本-这将需要大约9700000*9700000/1000个字符的空间,尽管垃圾收集器可能会过来救你,但这是一项非常繁重的分配工作。

    如果避免使用类的名称(例如“StringBuilder”)作为变量的名称,那么您和其他人的生活都会得到改善。使用不同的命名约定(例如,在变量上以小写字母开头)

        2
  •  2
  •   Nick    14 年前

    我不确定这个循环是否会终止。

    是不是应该是:

    for(int i=0;i<800; i+= 1000 )
    {
        String SStr=MyString.Substring(i,1000);
    }
    

    以便 i 正在增加。

    您还需要更改上限(i<800)

    或许你真正想做的是:

    for(int i=0;i<800; i++)
    {
        String SStr=MyString.Substring( i * 1000 ,1000);
    }