Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Memory usage by a Type 2

Status
Not open for further replies.

paulbent

Programmer
Mar 4, 2002
1,071
GB
Concerning the members of a user defined data type, does anybody know if VB stores variables of certain data types on architecture-dependent boundaries or do they occupy consecutive bytes of memory?

For example is an Integer always stored on a 2 byte boundary, a Long on a 4 byte boundary, a Double on an 8 byte boundary etc?

If so, the order in which members of a type are defined would be important so as not to waste memory.

Paul Bent
Northwind IT Systems
 
here is a snippet of hypothesis from cajuncenturian in thread222-462075 (maybe it helps maybe it doesnt)

Not sure of what this means, but test result data yield the following hypotheses:

In an UDT, each Boolean and Integer will require 2 bytes, Longs and Singles need 4, and Doubles need 8. Both Len and LenB return the sum of these numerical data types.

Things get interesting when Strings are introduced into the UDT. If you use a variable length string, then 4 bytes will be required for the string pointer,

<Begin Conjecture>
but it appears that the string pointer must be word aligned (on a 4 byte boundary) and whereas the Len function will dutifully add the proper 4 pointer bytes, the LenB may add an additional two bytes for each string pointer that is shifted by two bytes to insure word alignment. It also appears that if a string type is used in the structure, then the structure ends on a word boundary.
<End Conjecture>

For example:
Type UDTOne
Number1 as Integer
String1 as String
String2 as String
Number2 as Integer
End Type

Len(UDTOne) = 12 : LenB(UDTOne) = 16

Type UDTTwo
Number1 as Integer
String1 as String
String2 as String
Number2 as Integer
Number3 as Integer
End Type

Len(UDTTwo) = 14 : LenB(UDTTwo) = 16

Type UDTThr
Number1 as Integer
Number2 as Integer
String1 as String
String2 as String
End Type

Len(UDTThr) = 12 : LenB(UDTThr) = 12

The difference is that in the first structure, the first string begins 2 bytes into the structure, and since that is not on a word boundary, 2 bytes are added before the 4 byte string pointer. That puts the end of the structure 14 bytes into the structrue, require 2 more bytes to word align the end of the structure. Since 4 bytes have added into the structure to word align the string pointers and structure end, LenB reports 16 rather than the actual 12 being used.

In the second case, the end of the structure is already at a word boundary, so only two bytes have been added, those being to word align the string pointers.

In the third structure, the strings are already word aligned, as is the end of the structure, so no padding is required.

Fixed length strings do not seem to require word alignment, probably because we're dealing with actual values, rather than memory addresses, but there is a quirk here too. The Len function will return the length of the string, but the LenB returns the bytes required to store the string, and since the default string representation in VB is Unicode format, each character requires two storage bytes, so

Type UDTThr
String1 as String * 11
End Type

Len(UDTThr) = 11 : LenB(UDTThr) = 22

Now, as to how we use this information to properly determine the value to use in the size parameter of the API call, I'm not quite sure just yet.


good luck!

If somethings hard to do, its not worth doing - Homer Simpson
------------------------------------------------------------------------
come on... get involved!
To get the best response to a question, please check out FAQ222-2244 first
A General Guide To Excel in VB FAQ222-3383
 
ADoozer,

Thanks for the response and the link, that's very interesting; I hadn't thought of testing it myself with LenB.

It confirms that Type members should be defined in highest to lowest storage sequence with fixed length strings at the end so as not to waste memory, eg:

MyType
vntA As Variant
dblB As Double
lngC As Long
strD As String
intE As Integer
strF As String * 10
End Type

Paul Bent
Northwind IT Systems
 
Integer, Boolean, String are word aligned (even 2 byte boundary). Long, Single, Double, Date, Currency, Decimal, Object, Variant are longword aligned (even 4 byte boundary). Byte seems to be byte aligned...


 
Strongm,

Thanks that explains it very concisely. So one just has to define the longword aligned members before the word aligned.

That's quite different from another language (LotusScript) which I often use and is very similar to VBA. A double for example (according to the documentation) is aligned on an 8 byte boundary so if you did

MyType As Type
dblNum1 As Double
intNum2 As Integer
dblNum3 As Double
End Type

You would have 6 bytes of unused memory from intNum2 to dblNum3. Strange but true!

Paul Bent
Northwind IT Systems
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top