加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

OMG!内存操作真危险

发布时间:2020-12-16 23:31:21 所属栏目:大数据 来源:网络整理
导读:版权声明 :可以任意转载,转载时请务必以 超链接形式 标明如下文章原始出处和作者信息及 本声明 作者: xixi 出处: http://blog.csdn.net/slowgrace/archive/2009/04/24/4105426.aspx 在 这篇文章 里提到把API参数声明为ANY和声明为LONG的区别。昨天在这个

版权声明:可以任意转载,转载时请务必以超链接形式标明如下文章原始出处和作者信息及本声明

作者:xixi

出处:http://blog.csdn.net/slowgrace/archive/2009/04/24/4105426.aspx

这篇文章里提到把API参数声明为ANY和声明为LONG的区别。昨天在这个帖子里试了试,还真是那么回事。感谢myjian耐心解释。

话说有个API函数叫RtlMoveMemory,我们可以有以下两种声明:

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

然后我们用下面的测试代码:

Option Explicit

Private Type MyStruct
x
As Byte
y
As Byte
z
As Long
End Type

Private Sub Form_Load()
Dim t As MyStruct
With t
.x
= 12
.y
= 34
.z
= &H5678 '在内存中存放为 &H78 &H56 &H00 &H00
End With

Dim p As Long
Dim b As Byte
p
= VarPtr(t)

Call CopyMemory(b,ByVal p + 2,1)
Debug.Print Hex(b)

Call CopyMemory(b,ByVal p + 4,1)
Debug.Print Hex(b)
End Sub

这段代码大致的意思,是要验证VB6中结构的高字节对齐存储方式。

如果用第一种声明就会导致内存溢出(我昨天尝试的后果是ACCESS死掉重启),用第二种就不会。主要是下面这个语句

Call CopyMemory(b,ByVal p + 2,1)

这个语句的第二个参数是为了把P变量内的值(也就是变量t的内存地址)+2之后的那个"值"传进去,而不是P这个变量的地址,所以要加上BYVAL,因为声明里默认是ByRef。而当声明里面不是声明为ByRef As Any而是ByVal As Long时,这个调用就可以是p+2了,可以省去ByVal说明。

而这个语句的第一个参数是要把变量b的地址传过去,如果使用ByVal as Long式声明的话,这样传进去的就是b的值(当时是0),向着0这个地址复制数据,当然会出错了。实际上,如果用ByVal as Long式声明的话,应该传vatPtr(b)才对。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读