procedure ChangeVariant(s:string);
var
 V:Variant;
begin
  V:=s;
  TVarData(V).VType:=VarInteger;
  TVarData(V).VInteger :=32;
  V :=34;
end;书中说:"虽然这段代码看起来很安全,但它可能引起内存错误.作为一条普遍的规则,请不要直接访问TVarData的数据域."  这句话应该怎么理解?为什么说会引起内存错误?

解决方案 »

  1.   

    Variant只是一个Union结构,除了几个基本类型,还有指针类型的,操作基本类型不会有什么问题,但是如果操作的是指针类型,那结果就完全不一样.因为你把一个指针交给了Variant,但是实际上这个指针指向的内存却被你释放掉了,那么Variant当中实际存储的是一个野指针,这个时候就出问题了.
      

  2.   

    procedure ChangeVariant(s:string); 
    var 
    V:Variant; 
    begin 
      V:=s;   //V中分配内存,存放一个pascal string, VType被设定为varString (1)
      TVarData(V).VType:=VarInteger;  //直接修改VType为varInteger; (2)
      TVarData(V).VInteger :=32;      
      V :=34; //由于V中原来是varInteger(在(2)中修改的内容),因此,此句相当于直接修改TVarData(V).VInteger := 34;      
    end; 我们再来看本该执行的操作 (//后是我写的伪代码)
    procedure ChangeVariant(s:string); 
    var 
      V:Variant; 
    begin 
      V:=s;   
      //此句相当于如下代码:
      //TVarData(V).VPointer = GetMem(Length(s));
      //TVarData(V).VType := vtString;  V :=34; 
      //此句相当于如下代码:
      // if TVarData(V).VType = vtString then
      //   FreeMem(TVarData(V).VPointer;
      // TVarData(V).VType := vtInteger;
      // TVarData(V).VInteger := 34;
    end; 所以,关键点是有内存没有释放.简单来说就是产生了内存泄露.