我使用以下方法通过和操作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;调试时,在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在大多数Insert()语句之后正确引用s上的字符,并在调用Insert()之后突然停止工作
)我在打字时发现了我问题的答案。答案现在看来是显而易见的,但在我努力解决这个问题的时候却不是这样。也许贴出这个问题和答案会对其他人有所帮助。)
发布于 2013-02-22 01:31:57
调用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;https://stackoverflow.com/questions/15015376
复制相似问题