Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Delphi7,字符串问题_String_Delphi_Assembly_Delphi 7 - Fatal编程技术网

String Delphi7,字符串问题

String Delphi7,字符串问题,string,delphi,assembly,delphi-7,String,Delphi,Assembly,Delphi 7,在我的项目中,我遇到了字符串“内存不足异常”的问题,MM没有被使用。当字符串长度达到2 300000个符号时,问题就出现了。尽管有足够的内存,并且在代码的同一部分中,我可以创建一个包含100000000个字符的sting 谷歌没有帮助,我无法分解它(没有技能),所以我决定创建一个最小的测试示例,在这个示例中,我可以获得小于200000个符号的字符串的内存异常。我不能创造这样的例子,但我创造了一些奇怪的东西: program Project2; {$APPTYPE CONSOLE} uses

在我的项目中,我遇到了字符串“内存不足异常”的问题,MM没有被使用。当字符串长度达到2 300000个符号时,问题就出现了。尽管有足够的内存,并且在代码的同一部分中,我可以创建一个包含100000000个字符的sting

谷歌没有帮助,我无法分解它(没有技能),所以我决定创建一个最小的测试示例,在这个示例中,我可以获得小于200000个符号的字符串的内存异常。我不能创造这样的例子,但我创造了一些奇怪的东西:

program Project2;
{$APPTYPE CONSOLE}
uses
   SysUtils;

var s : string;
    k : integer;

function b : string;
begin
 result := 'f';
end;

procedure c;
var ss : string;
begin
  s := s + '{' +  b + '}';
  ss :=  'a';

  if k mod 100001 = 0 then
  begin
     // ss[1] := 'd';    // uncoment me
     write(k mod 10);
  end;

  inc(k);
end;

begin
  while true do c;
end.
这段代码运行良好。它只是通过一些额外的操作将某些内容添加到全局字符串中。问题是,如果取消对标记字符串的注释,它将显著减慢(无论是否进行优化)。考虑到这个赋值在100001次迭代中只有一次,它不能减慢速度

问题:

  • Delphi中的默认字符串是如何工作的

  • 如何避免减速

  • 如何避免内存不足

  • 另外,如果我在主项目中加入FastMM,错误就会消失
    p、 p.s未注释字符串的示例在3分钟内(从用户模式)将我的Windows 7发送到BSOD。

    通过执行以下操作分配字符串

    s := s + '{' +  b + '}';
    
    在一个长时间运行的循环中,它只会使你的记忆片段化。您可能有足够的内存来存储字符串,但这还不够。您需要内存是连续的,但是您的分配模式会使这变得很困难


    通过调用
    SetLength

    1,将字符串预分配到其最终所需长度,从而解决此问题。Delphi中的默认字符串如何工作?

    每次受影响时(通过
    :=
    )都会分配一个新的
    字符串

    就是

    s := s + '{' +  b + '}';
    
    将为
    s+'{'+b+'}'分配一个
    字符串
    ,然后将其复制到变量
    s

    每次运行这一行时,都有一个内存分配和一个内存释放。这可能很慢,即使使用FastMM4。但对于老MM来说,速度可能会非常慢

    2。如何避免减速?

    如果您使用的是旧的Delphi,使用“Borland”内存管理器,则分配和重新分配非常缓慢。它会使记忆碎片化很多

    ss[1]:='d'
    当然非常慢,这是由于内存碎片,而且Borland内存管理器必须对此行的内存分配进行一些缓慢的清理

    将行更改为:

    var ss: string[1];
    
    而且它不会再慢下来,因为
    shortstring
    将在堆栈上分配,而堆不会被使用

    因此,为了避免减速:

    • 使用现代内存管理器,如FastMM4
    • 使用
      TStringBuilder
      类,或者使用一个好的、旧的
      TMemoryStream
      在其中添加数据:内存重新分配会少得多,因此速度会快得多
    3。如何避免内存不足?

    内存不足错误来自内存碎片

    所以前一个问题的两个解决方案将解决这个问题