繁体   English   中英

奇怪的StrPCopy()AV错误和变通办法似乎没有意义

[英]Strange StrPCopy() AV error and workaround that does not seems to make sense

我在处理StrPCopy()时遇到一个奇怪的问题。 请查看以下示例代码:

procedure TForm2.butnTestClick(Sender: TObject);
var
  s : string;
begin
  //-- assign string this way will cause AV when trying to StrPCopy()
  s := 'original string';

  //-- assign string this way works!!!!!!!
  //s := Trim('original string');

  //-- AV error when trying to alter the string
  StrPCopy(PChar(s), PChar('changed'));

  //-- should come back with "changed"
  Memo1.Lines.Add(s);
end;

我正在使用Delphi 10 Seattle。 如果尝试使用StrPCopy()更改“ s”,则会出现AV错误。 但是,我用Trim()包围了字符串声明,它将起作用。

好像用Trim()将字符串声明括起来一样,会触发编译器关闭对该特定字符串的某种排序优化。 我只是不知道那是什么。 请帮忙。

s引用文字时,它指向只读存储器。 因此,访问冲突。

使用Trim编写可写字符串时,可以将其覆盖而不会出现运行时错误。 也就是说,由于空终止符和长度不匹配,您仍然破坏了字符串。

您的主要问题是将Delphi字符串与以N结尾的C字符串混合。 停止这种虐待,您的问题就会消失。 根本没有理由调用StrPCopy 一旦停止这样做并使用本机Delphi字符串,就不会遇到任何此类问题。

编写代码的正确方法如下:

s := 'changed';

您使用StrPCopy()调用并不安全-不管使用通过Trim()分配创建的新字符串消除了AV还是什么。

字符串数据类型比PChar更复杂。 它具有一个长度组成部分,神奇地位于指针和字符数据的前面。 强制转换为PChar可以,但是只能用于阅读。

通过将字符串强制转换为PChar,可以让StrPCopy将“已更改”的字符串放入内存的该部分。 在您的示例中,您正在复制一个较小的字符串,因此您可以明智地使用内存。 结果是一个非常混乱的字符串(长度与字符串不匹配,中间有一个空字符),但是您在它的范围之内。

如果您的代码是类似...

StrPCopy(PChar(s), PChar('changed to this string'));

...那么您的代码将覆盖字符串的内存占用量以上-通常没有立即的AV。 您可能会摆脱这个。 你不可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM