我写了这段代码,并在其中得到了AV。
procedure TForm1.Button1Click(Sender: TObject);
Var
C : Pchar;
s : string;
begin
c:= PChar('*');
s := string(c); // AV here , but code works if i put C:= PChar('**')
ShowMessage(c);
end;我不明白为什么.Does会有人知道?
提前谢谢。
发布于 2013-06-19 22:11:44
AV意味着错误地使用内存。从任何地方获取数据,或者写入任何地方。
问题来自不同类型的数据。
'*‘
是Char,但是
'**‘
是字符串
这将很好地与您的代码一起工作:
procedure TForm1.Button1Click(Sender: TObject);
Var
C : Pchar;
s : string;
begin
c:= PChar(string('*'));
s := string(c); // AV here , but code works if i put C:= PChar('**')
ShowMessage(c);
end;发布于 2013-06-19 21:55:58
使用一个字符的字符串文字,您将类型转换为Char,而不是string,因此它不是一个指针。当你将它转换回来时,它仍然不是一个真正的指针,尽管它声明了类型,所以它不能被转换为字符串。
如果您发现自己的类型转换为字符串文字,那么您可能正在做一些不必要的事情。尽管您可以提示它应该使用哪种类型,但正如这里的其他答案所演示的那样,编译器已经检测到文本需要使用哪种类型,并且通常是正确的。只需将文本直接赋值给变量,而不进行任何强制转换。
如果你完全省略了类型转换,你的代码对于你想要的任何长度的字符串都同样有效:
// All PChar assignments, no casting
c := '';
c := '*';
c := '**';此外,转换回string也是不必要的。您可以直接分配一个PChar,编译器会自动进行转换:
s := c;发布于 2013-06-20 14:52:30
事实上,
c:= PChar('*');被编译为
mov [c],$0000002a就好像它是这样写的:
c:= PChar(ord('*'));由于ord('*')=$2a,看起来'*'字符被类型转换为一个整数(NativeInt),然后这个整数被转换成一个指针。因此,当您尝试访问c内容时,您将访问无效的内存地址$0000002a,并触发访问冲突。
编译时:
c:= PChar('**');它的生成方式为
mov eax,$00548984
mov [c],eax在这种情况下,编译器在可执行文件中生成一个常量#0结尾的文本缓冲区(而不是Delphi string),并将c设置为其地址。
PChar('*')表现不同的事实是char类型的一种“优化”,可以将其类型转换为整数。
但我明白这可能会让人感到困惑。
如果你只想要一个指向单个'*‘的指针,你可以这样写:
c:=PChar('*'#0);
c:=PChar(string('*'));它将按预期工作,因为两者都将绕过对字符序数值的强制转换。
https://stackoverflow.com/questions/17191779
复制相似问题