Delphi AnsiString操作 - PAnsiChar变得腐败?

Jam*_* L. 1 delphi pointers ansistring delphi-xe2

我使用以下方法来移动和操纵AnsiString.它大部分时间都有效,但有时指向字符串的指针退出运行.给出以下代码:

var
  s: AnsiString;
  p: PAnsiChar;
  offset, idx, cnt: Integer;
begin
  s := 'some>very>long>string>with>field>delimiters>';
  p := @s[1];
  offset := 1;

  // find the 5th field
  cnt := 5;
  repeat
    idx := AnsiString.AnsiPos('>', p);
    Inc(p, idx);
    Inc(offset, idx);
    Dec(cnt);
  until cnt = 0;

  // insert a new field after the 5th field
  Insert(AnsiString('something new>'), s, offset);

  // skip other fields
  // insert other values
  // repeat
end;
Run Code Online (Sandbox Code Playgroud)

调试时,在repeat..until循环结束后,您可以查看检查器并查看p = 'field>delimiters>'.在之后Insert()的语句,s = 'some>very>long>string>with>something new>field>delimiters>'并p = 'something new>field>delimiters>'在督察.这是预期的.

我真正的字符串长达数千个字符.这种在字符串中移动并添加新字段的方法可以工作几十次,然后突然停止工作. p调用后不再显示字符串前面的插入值Insert(). p似乎并不知道s已经改变了......

为什么在大多数语句后p正确引用一个字符,并在一些调用后突然停止工作?sInsert()Insert()

(我在打字时发现了我的问题的答案.答案现在看来很明显,但在我遇到问题的时候并不是这样.也许发布问题和答案会帮助其他人...)

Jam*_* L. 7

当您调用时Insert(),AnsiString如果没有足够的额外连续内存来扩展其当前内存位置的缓冲区,内存管理器将移动到内存中的新位置.这留下p指向旧的内存位置,该位置不包含修改的字符串,并且可能导致访问冲突.

p在每个Insert()语句之后添加一行代码以重新初始化问题.

var
  s: AnsiString;
  p: PAnsiChar;
  offset, idx, cnt: Integer;
begin
  s := 'some>very>long>string>with>field>delimiters>';
  p := @s[1];
  offset := 1;

  // find the 5th field
  cnt := 5;
  repeat
    idx := AnsiString.AnsiPos('>', p);
    Inc(p, idx);
    Inc(offset, idx);
    Dec(cnt);
  until cnt = 0;

  // insert a new field after the 5th field
  Insert(AnsiString('something new>'), s, offset);
  p := @s[offset];                                 // <- this fixes the issue

  // skip other fields
  // insert other values
  // repeat
end;
Run Code Online (Sandbox Code Playgroud)