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