請考慮下面的程序:爲什麼這個PAnsiChar在轉換爲AnsiString時會被切碎?
program SO41175184;
{$APPTYPE CONSOLE}
uses
SysUtils;
function Int9999: PAnsiChar;
begin
Result := PAnsiChar(AnsiString(IntToStr(9999)));
end;
function Int99999: PAnsiChar;
begin
Result := PAnsiChar(AnsiString(IntToStr(99999)));
end;
function Int999999: PAnsiChar;
begin
Result := PAnsiChar(AnsiString(IntToStr(999999)));
end;
function Str9999: PAnsiChar;
begin
Result := PAnsiChar(AnsiString('9999'));
end;
function Str99999: PAnsiChar;
begin
Result := PAnsiChar(AnsiString('99999'));
end;
function Str999999: PAnsiChar;
begin
Result := PAnsiChar(AnsiString('999999'));
end;
begin
WriteLn(Int9999); // '9999'
WriteLn(Int99999); // '99999'
WriteLn(Int999999); // '999999'
WriteLn(string(AnsiString(Str9999))); // '9999'
WriteLn(string(AnsiString(Str99999))); // '99999'
WriteLn(string(AnsiString(Str999999))); // '999999'
WriteLn(string(AnsiString(PAnsiChar(AnsiString(IntToStr(9999)))))); // '9999'
WriteLn(string(AnsiString(PAnsiChar(AnsiString(IntToStr(99999)))))); // '99999'
WriteLn(string(AnsiString(PAnsiChar(AnsiString(IntToStr(999999)))))); // '999999'
WriteLn(string(AnsiString(Int9999))); // '9999'
WriteLn(string(AnsiString(Int99999))); // '9999' <----- ?!
WriteLn(string(AnsiString(Int999999))); // '999999'
ReadLn;
end.
只有在這些情況下,一個沒有串失去一個字符,在2010年德爾福和Delphi XE3兩者。使用FPC,相同的程序可以正常工作。切換到PChar
也會使問題消失。
我想這與內存管理有關,但我沒有足夠的線索去尋找有意義的調查。任何人都可以澄清?
我可以理解推理,但我仍然覺得它很好奇它是如何出現在這些值中的一個。它在我的示例程序中發生,與我正在調試的程序中的方式完全相同。例如,我希望它有時可以工作,有時候不會。什麼可以解釋這種一致性和值之間的差異? –
@ThijsvanDien分配器很難預測,但相當確定。如果它在你的程序的一次執行中表現出某種特定的方式,那麼在所有執行過程中它都會有這樣的表現。還有一點是'9999'的長度是4的平方倍數。內存塊通常與4字節的邊界對齊,這就解釋了爲什麼部分覆蓋會覆蓋第五個字符。 – hvd
@Remy不開始語句的詞不應該大寫。返回指針的函數應該擔心所有的調用者,所以應該保持複數。關於具體什麼時候發生釋放是一個很好的注意事項,當我可以做一些額外的測試時,我會嘗試將它重新引入。 – hvd