通过指针修改字符串变量的内容是否安全?

Ast*_*oth 4 delphi

考虑我有一个Str参数传递参数的过程,我想通过过程修改给定变量的内容,例如

procedure Replace(var Str: string);
var
  PStr: PChar;
  i: Integer;
begin
  PStr := @Str[1];
  for i := 1 to Length(Str) do begin
    PStr^ := 'x';
    Inc(PStr);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这是一个可接受的指针用法吗?我不确定它是否有内存泄漏.

真正发生了什么PStr := @Str[1],编译器是否在Str内部复制,或者是什么?

这种代码优化值得吗?

mgh*_*hie 5

这是一个可接受的指针用法吗?

你需要确保不要打电话

PStr := @Str[1];
Run Code Online (Sandbox Code Playgroud)

对于一个空字符串,因为它会崩溃.最简单的方法是用.替换该行

PStr := PChar(Str);
Run Code Online (Sandbox Code Playgroud)

这样编译器将确保#0返回指向字符串的第一个char或指针的指针 .正如肯在评论中正确指出的那样,UniqueString()在这种情况下没有电话,所以你需要自己做.

我不确定它是否有内存泄漏.

不,没有内存泄漏.获取指向字符串字符的指针将在UniqueString()内部调用,但这也会发生对字符串字符的写访问,因此字符指针没有什么特别之处.

在PStr中真正发生了什么:= @Str [1],编译器是否在内部制作了Str的副本,或者是什么?

不,它只是确保字符串是唯一的(因此通过指针的写访问不会更改共享相同数据的任何其他字符串的内容).然后它返回一个指向字符串中该字符的指针,然后您可以将其视为任何其他PChar变量,将其传递给API函数,递增它等等.

这种代码优化值得吗?

它不仅值得,它必须真正实现大字符串的良好性能.这样做的原因是编译器不够智能,只能调用UniqueString()一次,但是对于字符串中字符的每次写访问,它都会插入调用.因此,如果逐个字符处理大字符串,那么所有这些调用都会产生很大的开销.