function Test( s:string ):Pointer;
var
  ary : array [0..255] of char;
begin
  strpcopy( ary, s );
  result := @ary[0];
end;procedure TForm1.Button1Click(Sender: TObject);
begin
  caption := strpas( Test(Edit1.Text) );
end;在函数Test中ary应该是一个临时变量吧?函数结束时此变量应该自动消亡吧?可是为什么此函数可以返回正确的结果呢?

解决方案 »

  1.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      p : pointer;
    begin
      p := Test(Edit1.Text);//Test函数的临时变量ary仍未消亡
      caption := strpas( p );//可以得到正确的结果
      freemem(p,256);//但是无法释放这片内存,会出错
    end;
      

  2.   

    ehom(?!) 说的是对的,返回的是一个地址,虽然你free了 但是地址还是存在的!
      

  3.   

    上面静态的数组是利用函数的栈空间储存数据,这个和利用FreeMem释放堆内存是不一样的,如果是堆上分配的内存,是会导致异常的
      

  4.   


    看看如下代码  你会发现再第二个中的字符已经不是原来的那个了,所以在第一个作用域结束的时候已经被释放了先执行第一个BUTTON  然后再执行第二个BUTTONfunction Test( s:string ):Pointer;
    var
      ary : array [0..255] of char;
    begin
      strpcopy( ary, s );
      result := @ary[0];
    end;var
    P:Pointer;procedure TForm1.Button3Click(Sender: TObject);
    begin
      P:=Test(edit1.text);
      Form1.Caption := strpas(P);
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      MessageBox(0,p,p,mb_ok);
    end;
      

  5.   

    这是一个编译器实现问题 也许其他版本的DELPHI和C不是这样 。
    在BUTTON3中 的作用域下不会释放,而在这个之后便会释放栈空间数据。
      

  6.   

    谢谢大家,基本明白了
    现在我想知道,在多线程程序中,如果每个线程都调用函数Test会出问题吗?>>上面静态的数组是利用函数的栈空间储存数据是不是不同的线程调用这个函数时,ary分配在不同的栈空间上呢?
      

  7.   

    好象线程的调用是和这是一样的  每个线程都有自己的地址  每个地址都有自己的栈在分配的时候如果出现LOCK事件,他会把自己的退栈,然后并保存栈,这和WINDOWS机制有关系.你可以看看ESP 这个是指向RESULT的指针.具体由于我经验有限,也只能到这了