[RESOLVED] Copymemory array
Hello!
Code:
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dst As Any, ByVal iLen&)
Dim X As Long, Y As Long
ReDim Source(0 To 500, 0 To 5) As String
For X = 0 To 5
For Y = 0 To 500
Source(Y, X) = "Item " + CStr(Y) + " in col " + CStr(X)
Next Y
Next X
ReDim out(UBound(Source, 1)) As String
CopyMemory ByVal VarPtr(out(0)), ByVal VarPtr(Source(0, 2)), 4 * (UBound(out) + 1)
ZeroMemory ByVal VarPtr(Source(0, 2)), 4 * (UBound(out) + 1)
Erase Source
MsgBox "125th element: " + out(124) + vbNewLine + "126th element:" + out(125)
End
By using this code you can simply move a 2d string arrays one indexed dimension into a single dimension array.
But if you change the variable type to Variant, everything goes to wrong. It copies the first 125 element (0-124), but after the 125th element it copies only null strings.
Do you have any ideas how can i fix this code?
Ok ive found it. Variant type string variants has 8 byte long pointers, but strings has 4. So i have to copy the 8 byte long pointers to get it to work. :)
Re: [RESOLVED] Copymemory array
Quote:
Originally Posted by LaVolpe
If your arrays are large, you may want to entertain idea of converting variant to string pointer. Why? Using 500K as example: 16 byte Variant requires 8mb of memory, but 4 byte string pointer, 2mb memory requirement. The logic is simple, but does require a loop, significant changes only...
Code:
ReDim out(UBound(Source, 1)) As String
For Y = 0 To 500
CopyMemory ByVal VarPtr(out(Y)), ByVal VarPtr(Source(Y, 2)) + 8, 4& ' string pointer in variant
CopyMemory ByVal VarPtr(Source(Y, 2)) + 8, 0&, 4& ' clear string pointer in variant
Next
MsgBox "125th element: " + out(124) + vbNewLine + "126th element:" + out(125)
Thanks for sharing this useful piece of code :)
Re: [RESOLVED] Copymemory array
To finish up. This little hack can be used to convert Variant arrays containing numerical data to a array of just numerical data too. The final 8 bytes in the Variant structure contains the actual numerical data. If the numer is a byte, then just 8th byte used, Longs: 8-11 used, Doubles: 8-15 used.
For example the passed Variant array contains only longs
Code:
ReDim out(UBound(Source, 1)) As Long
For Y = 0 To 500
CopyMemory out(Y), ByVal VarPtr(Source(Y, 2)) + 8, 4& ' Long value in variant
' no need to erase anything, numerical data are not pointers
Next
And if the Variant array contained only Integers
Code:
ReDim out(UBound(Source, 1)) As Integer
For Y = 0 To 500
CopyMemory out(Y), ByVal VarPtr(Source(Y, 2)) + 8, 2& ' Integer value in variant
' no need to erase anything, numerical data are not pointers
Next
And if the Variant array contained only Dates
Code:
ReDim out(UBound(Source, 1)) As Date
For Y = 0 To 500
CopyMemory out(Y), ByVal VarPtr(Source(Y, 2)) + 8, 8& ' Date value in variant
' no need to erase anything, numerical data are not pointers
Next