请考虑下面的程序:为什么这个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