function test():integer;
var
 ary:array [0..100] of char;
begin
  ary[0]:=#0;
  result:=integer(@ary)+integer(ary[0]);
end;上面的一段代码,每次返回的ary的地址都是一样,如果在线程中调用这样的函数,加入test()的处理时间比较长才退出,会不会出现ary还在处理的时候,被另外一个调用覆盖数据?如果会的话,那就产生脏数据了,要怎么避免?
如果不会,为什么?他们的地址都是一样的,那操作的都是相同的一段内存吧?还是我这样返回得到的只是对于函数入口地址的偏移量?

解决方案 »

  1.   

    作如下修改
    1 array改为全局
    2 线程对array操作加锁
      

  2.   

    稍微持一点保留意见,首先局部变量用完释放是对的,但是delphi的内存分配机制不是把内存还给系统,而是保留给下次使用(LZ所说的上面的一段代码,每次返回的ary的地址都是一样也应该就是碰巧遇到了这种情况)Lz的代码有一部分是直接操作数组指针的地址,这种操作本身非常不安全,很容易修改不该修改的内存地址,轻则造成脏数据,重则异常退出,当多线程时,这种使用尤为致命,所以如果想多线程操作同一个array就按照2L进行修改,如果只是调用函数我觉得应该避免出现integer(@ary)这样的代码
      

  3.   

    function test():integer;
    var
     ary:array [0..100] of char;
    begin
      ary[0]:=#0;
      result:=integer(@ary)+integer(ary[0]); //这一句???  integer(ary[0]) 难道不是必0?
      
    end;
    你这个 返回值 其实就是  内存分配 给 ary 的地址当你提交慢的时候, 这一段内存已经被系统回收了, 下次分配还是这个,所以你感觉值不变。如果用大量线程的话, 这个值绝对不是相同的。所以尽管放心好了。 
      

  4.   

    我还是认为这样做不对,虽然线程间局部变量的安全是由系统保证的,但是LZ的代码是返回该数组的地址,做个假设,线程1调用函数得到了一个array的地址,此时函数执行结束,数组释放,但是返回的地址被线程1保留 而线程2恰巧分配到了一个相同的地址,而此时线程1尝试对该地址进行修改,难道程序能保证执行结果正确么?
      

  5.   

    上面的代码只是测试,验证每次进到那个函数的时候操作的那个数组是否是同一个内存.不会有任何局部指针返回给上一层的。出错的代码是在DLL中的一个接口函数,有类似ary这样的局部数组变量.项目合作方的程序是VC写的.在调用DLL中的接口函数一段时间后,有时会出现
    Access violation at address 00521E6B in module 'xxx.dll'. Write of address 01348D52
    这样的错误,由于是不是每次都出现,所以很难捕捉到错误的原因.另外,想请教一下,
    1.写的DLL给第3方程序调用时,接口参数全部是按C标准.不知道进入DLL的接口函数后,函数里用String性的变量会不会有问题?
    2.3楼提到的直接引用数组的指针会出现写了不可写的地址,在函数内部的局部使用,也会出现这样的情况吗?不甚感激~
      

  6.   

    http://www.cnblogs.com/del/category/323943.html
    万一博客里51多条,看有没你要的。
      

  7.   

    我怎么发这里,发错了,还是csdn乱了,  上面用线程我觉得意思是会有乱的,多线程操作是会有影响的, 我用的时候加个临界区来控制。
      

  8.   

    function test(f:integer;v:char):integer;
    var
     ary:array[0..10] of char;
    begin
      ary[0]:=v;
      sleep(3000);
      showmessage(inttostr(integer(@ary))+' '+inttostr(f)+':'+inttostr(integer(ary[0])));
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      timer1.Enabled:=true;
      timer2.Enabled:=true;
    end;procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      timer1.Enabled:=false;
      test(1,#63);end;procedure TForm1.Timer2Timer(Sender: TObject);
    begin
      timer2.Enabled:=false;
      test(2,#65);end;通过上面的代码测试,ary的数组的地址不是一样的,跟1楼说的一样。只是不知道DLL中为什么报地址写错误,头晕了