当前位置:编程学习 > VB >>

数组在内存中是连续存放的吗

有一个API函数声明如下:
1、在C中的声明如下:
int rf_load_key(unsigned char *_NKey);
2、在VB中的声明如下:
Declare Function rf_load_key Lib "mwrf32.dll" (ByRef nkey As Byte) As Integer

调用的代码如下:
     dim akey(6) As Byte

    akey(0) = &H33
    akey(1) = &H34
    akey(2) = &H28
    akey(3) = &H51
    akey(4) = &H69
    akey(5) = &H78
    sector = 1
    call rf_load_key(akey(0))  

    显然这个函数的参数ByRef nkey As Byte是需要一个存放在连续内存中的内容,
     现在的问题是 akey这个数组在内存中是连续存放的吗,有相关的资料介绍吗,谢谢大家。

 dim akey(6) As Byte,他已经定义了这固定长度,肯定是连续放了 高手呢,出来 REDIM PRESERVE这种操作时,内存会不会连续就不清楚了 刚用CE测试了一个数组的内存位置。得出以下结论:

1.数组存的的位置在内存中是连续的
  不管你是采用 Dim Arr(3) as byte
    or(Dim Arr() as byte : redim arr(3)) as byte
    or(dim arr() as byte : ReDim Preserve Arr(N) as byte)

2.数组实际所在内存中的地址是可变的。
  当你采用 dim arr() as byte : ReDim Preserve Arr(N) as byte 方式时。
  数据所在的地址是变化的,主要取决于当前数据所在地址后面是否有空间,如果有空间后面直接增加。
  如果没有空间则别行分配地址
当然是连续的。毋庸置疑。 数组内部,只有一个指向实际数据的指针,你说,是不是连续的咯 应该是的,这样才好保证高效啊。一些语言还支持稀疏数组,就不知他们是怎么搞的了 通常情况下是的,除非你的数组非常的大,大到系统不能给你分配一块足够大的连续内存区域。
参阅一下这本书,里面有关于数组的深入介绍:
http://download.csdn.net/detail/veron_04/1371398
引用 8 楼 Veron_04 的回复:
通常情况下是的,除非你的数组非常的大,大到系统不能给你分配一块足够大的连续内存区域。

程序通过逻辑地址访问数据,无论数据存放在物理内存块还是缓存文件中,逻辑地址上始终是连续的。
引用 9 楼 Tiger_Zhao 的回复:
Quote: 引用 8 楼 Veron_04 的回复:
通常情况下是的,除非你的数组非常的大,大到系统不能给你分配一块足够大的连续内存区域。

程序通过逻辑地址访问数据,无论数据存放在物理内存块还是缓存文件中,逻辑地址上始终是连续的。

是的,至于物理地址,那是OS的事情 内存是分段的。但可以理解为是连续的。
显然是连续的。 所以循环中放redim以及字符串频繁&运算会影响速度,都不是很好的用法。 我们使用的都是逻辑内存,可以看作是一个文件,拥有一个地址就可以连续访问后面的数据.

dim I() as byte, J as long, K as long
    
redim i(0)    
text1.text=""

for j = 0 to 200
    k=k+1
    if k=16 then
        k=0
        text1.text=text1.text & right("00" & hex(i(j)),2) & vbcrlf
    else
        text1.text=text1.text & right("00" & hex(i(j)),2) & " "
    end if
next

这个代码会显示出数组I后面的一堆内存内容.

不过需要编译后才有用,并且编译选项中需要勾上"取消数组越界检查".

对于redim的情况,VB会看当前地址后面的可用内存空间够不够,如果够就直接扩,不够就重新申请一段足够的内存块,如果指定了preserve,就会复制原来的数据到新位置.
引用 8 楼 Veron_04 的回复:
通常情况下是的,除非你的数组非常的大,大到系统不能给你分配一块足够大的连续内存区域。
参阅一下这本书,里面有关于数组的深入介绍:
http://download.csdn.net/detail/veron_04/1371398


无论多大,都是连续的。

当然这是说的逻辑内存。Windows操作系统的物理内存,按照4KB分页,所以可以保证4KB内绝对是连续的,至于超过4KB,天知道。 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533
VB 数组不同于C数组,虽然存放都是连续的
VB调用DLL 中的C函数的几种种方式(数组作为形参)

C maxof.c:
__stdcall long maxof(long a[],int n)
{
if(n<=0)return -1;
{
long m =a[0];
long i;
for(i=1;i<n;i++) if(a[i]>m) m =a[i];
}    
return a[i];
}

VB:
'1)数组参数当作指针,值传递,传递第一元素(序号=0)的地址
'   指针声明为 LONG 类型
'声明
public declare function maxof lib "maxof.dll" (byval a as LONG ,byval n as LONG)as long
'调用
dim x(100) as long
dim m as  long
dim n as long 
n=100
for i=0 to 100-1
x(i) =i
next i
m = maxof(varptr(x(0)),n)
'2)第二种方式,数组按照引用传递,传递第一个参数(序号为0)
'声明
public declare function maxof lib "maxof.dll" (byref a as LONG ,byval n as LONG)as long
'调用
sub calcmax
dim x(0 to 100-1) as long
dim m as  long
dim n as long 
n=100
for i=0 to 100-1
x(i) =i
next i
m = maxof(x(0),n)
end sub
}

VB 调用自己定义的函数,可以采用以上两种方式,不过比较麻烦。

也可以直接传递数组,这是最好的方式。


'3) VB 内部使用数组,可以用任何方式传递参数
'可以直接传递整个数组
'定义函数:
function maxof (a() as long)as long
   dim lb as long,ub as long
   lb =lbound(a)
   ub =ubound(a)
   dim m as long
   dim i as long
   m= a(lb)
   for i=lb+1 to ub
   if(a(i)>m) then m=a(i)
   next i
   maxof =m
end function

'调用函数
sub calcmax
dim x(0 to 100-1) as long
dim m as  long
dim n as long 
n=100
for i=0 to 100-1
x(i) =i
next i
m = maxof(x)
end sub

PS:
VB数组,包含数组每一维度的大小信息,至少参数传递是这个样子的
数组数据本身,自然也是顺序存放的。
不过数组地址不是数据地址。
VB字符串也是如此,并且更复杂。


所以直传递数组,字符串,调用C动态库,和API一般直接传递,都是不行的。
要做一些处理,才可以使用。

不过VB.net 应该好用的多。


数组应该是个链表结构吧 
 
补充:VB ,  基础类
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,