首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

用 CopyMemory 拷贝 Type 为什么会死机

2013-01-11 
用 CopyMemory 拷贝 Type 为何会死机 ?Private Declare Sub CopyMemory Lib kernel32 Alias RtlMoveMem

用 CopyMemory 拷贝 Type 为何会死机 ?


Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Any, ByVal Source As Any, ByVal Length As Long)

Private Type QQ
  v1 As Long
  a() As Long
  b() As Long
End Type

Private Sub Form_Load()

  Dim a As QQ
  Dim b As QQ
   
 Call Redim_QQ(a)
 
 Select Case 1       
 
  Case 1: CopyMemory VarPtr(b), VarPtr(a), Len(a)  ' 只是要复制指针所以速度快 

  Case 2: Copy_QQ b, a                              

  Case 3: b = a                                    ' 这当然一定 ok, 但是复制次数一多会慢很多, 因为它一值重新配置 Array() + 复制  
  
 End Select
 
 
    With b
       
       For w = 1 To 10
          Debug.Print .a(w)  ' 全部 ok,  都可以看到正确数值 
       Next
    End With

   ' 惟独 跳出 sub 时会死机  

End Sub

Private Sub Copy_QQ(Store As QQ, Src As QQ)
    CopyMemory VarPtr(Store), VarPtr(Src), Len(Src)
End Sub
Private Sub Redim_QQ(b As QQ)
    With b
       ReDim .a(1 To 10)
       ReDim .b(1 To 10)
       
       For w = 1 To 10
          .a(w) = w
          .b(w) = w + 10
       Next
    End With

End Sub

[解决办法]
结构中的数组,CopyMemory函数并不能识别,因此复制的仅是数组的指针,却没有复制实际上数组的内容.

我没有跟踪以确认,不过从现象来看,虽然你能从第二个结构中正确读到内容,但那些内容全是指向第一个结构中的实际数据区的,所以在退出时,第一个结构变量的内存区域被回收了两次,导致出错.

因此,我认为在复制之后,查看结构A与结构B中数组元素的地址时,会发现是一样的,试试如下代码:

debug.paint hex(varptr(a.a(1))),hex(varptr(b.a(1)))

因为CopyMemory会认为你的结构是这样的:

Private Type QQ
   v1 As Long
   a As Long
   b As Long
 End Type


所以调用CopyMemory后,第二个结构变量中三个成员的值与第一个会是一样.

而V1本身就是值,因此地址不会一样,但值会一样.

至于A()与B()数组,直接就是指向了第一个结构变量中的内存区域了.

因此在退出时,VB自动回收了第一个结构变量的空间,但是在回收第二个结构变量的空间时,却又回收了刚刚才回收过的内存区域,所以肯定会挂的.

要想让它能工作,还是要自己处理数组.



不然就还是老实地用VB的等于号吧,嘿嘿.

热点排行