[英]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.