簡體   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