★★我发现delphi的一个bug,不相信大家试试下面的代码★★(10分)

  • 主题发起人 主题发起人 龙月
  • 开始时间 开始时间

龙月

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TForm1.Button1Click(Sender: TObject);
var dai:array of byte;
i:byte;
function x( zhi:array of byte;i:integer):string ;
var j:integer;
begin
result:='';
for j:=0 to i-1 do
begin
result:=result+char(zhi[j]);
end;

end;
begin
getmem(dai,26);
for i:=0 to 25 do
dai:=65+i;
memo1.Text:=x(dai,26);
end;

//这段代码执行后,在memo1里就会显示从A到Z的字符。
//但是,当你关闭窗口的时候就会报错。奇怪。难道是delphi的bug?
 
你代码的问题, 不是Delphi的Bug.

SetLength(dai, 26); //不能用getmem(dai,26);  
for i:=0 to 25 do
 
在D7下编译,没有出错,
你用的是什么版本
 
to tseug:
可以解释一下为什么吗?
 
简单的说,动态数组是采用垃圾回收机制有系统管理资源的释放,而你用GetMem申请内存后,
改变了dai的地址,是本应该指向动态数组的变量指向了错误的位置,当函数结束后,系统回
收资源时肯定会出错。另外,一个拥有26个元素的动态字节数组并不是26字节长度,这
样一来,申请26个字节是不够的,必然要访问到无效的区域.
 
对动态数组的分配不适和用 GetMem,因为事实上,在 GetMem 过后还有一些动作:)
用 SetLength 则编译器会处理这些动作。
那么是什么动作呢?和分配字符串差不多,系统在给动态数组申请空间的时候,不仅
要分配储存元素所需要的空间,还需要分配额外的 4 个字节存放数组元素个数,这
4 字节在所有元素前面,然后返回一个这 4 字节紧挨着的单元的指针,我们平时用的
就是这个指针。用 SetLength 则编译器就会做这些事情,而调用 GetMem 则你需要手
动处理这些,而显然你没有处理,所以出错:)
 
后退
顶部