To read the article online, visit http://www.4GuysFromRolla.com/webtech/041101-1.shtml

Variables, Values, and Arrays in VBScript (Part 2 of a 3-Part Series)

By Bill Wilkinson


VBScript Under the Covers
This article is Part 2 of a 3-Part article series by Bill Wilkinson. Part 1 of this series, Variables and Values in VBScript, examined how VBScript treated scalar variables: Strings and primitive data types. In this part, Bill delves deeper under the covers and looks at how VBScript handles both single and multi-dimensional arrays! Finally, in the third part, Object References in VBScript, Bill looks at object references and how VBScript handles copies of objects and arrays!

Arrays in VBScript
In the previous article in this series we looked at the basics of how variables and values are implemented in VBScript (and, with minor variations, in JScript). In this second part of the series, we'll focus on how VBScript represents and uses arrays.

As noted in the previous article, in VBScript all variables are always of the same kind or type, a VARIANT (which is in turn an OLE-defined structure). And a VARIANT instance always occupies 16 bytes of memory but only uses what is needed. The first two bytes of the VARIANT always indicate what the other 14 bytes are holding, and different types of data use pre-defined portions of those 14 bytes.

Enter, now, the array in VBScript. Much of this applies equally well to JScript, but there are some details in the two languages that are different enough that we will limit this discussion to VBScript, alone.

In conventional languages (C/C++/Java/Pascal/Fortran/many more), arrays are "homogeneous" and the type of each element of the array is defined when the array is created. So if, in C/C++, you did something like:

int arrayOfInt[ 100 ];

you would be allocating 100 integers, each occupying four bytes. But how is the space for those integers allocated? When you allocate an array, the system allocates contiguous memory sufficient to hold the requisite number of items. Simple as that: 100 integers, four bytes each? Fine: 400 bytes of memory all in one chunk.

The important part of this is that all elements of an array are always the same size. Then, when you ask for a particular element in the array [say via x = arrayOfInt(76)], the system simply multiplies the index [76 in the example] by the size of one item, adds that number to the address of the start of the array, and presto! It is addressing the proper spot in memory. In our example, 76 times four bytes per element is 304 bytes. We add 304 to the address of the beginning of the array and we have the address of element 76.

But VBScript is a "typeless" language. Right? Any element of any array can hold any data value. Right? So how does that work? How can the system know in advance how big each element should be? Simple: As we noted in the first article and reiterated above, every value in VBS is always an OLE VARIANT type! And that includes every element of every array! So every element of a VBScript array is 16 bytes in size. So VBScript, too, allocates contiguous memory for its arrays! And then we can just do the math, same as above, as needed.

So Dim ar(500) allocates 501 * 16 or 8016 bytes of memory. "But, but, but..." you say, "what if I put a long string into each slot of the array? 8016 bytes might not even be enough to hold one of the strings, let alone 501 of them!"

Referring back to part 1 of this series: "For all except the primitive data types ... the VARIANT contains a pointer to the actual data." The primitive data types are Empty, Null, Integer, Long, Single, Double, Date, Currency, and Boolean. Every other kind of data-including strings-is non-primitive and is represented in the variant by a pointer to the actual data.

A demonstration is in order:

<% 
  ar = Array("this","is","a","demonstration") 
  Response.Write ar(3) 
%>

This is what happens:

  1. First of all, the system figures out that the array you are creating has size 4 (elements 0 through 3). So it allocates 4 times 16 bytes and points the variable ar to those 64 bytes.

  2. Then it allocates space for a string containing "this" and puts the address of that string into slot 0 of the array; it sets the first two bytes of that slot to indicate that the VARIANT points to a string.

  3. Then it allocates space for a string containing "is" and puts the address of that string into slot 1 of the array; it sets the first two bytes of that slot to indicate that the VARIANT points to a string.

  4. Then it allocates space for a string containing "a" and puts the address of that string into slot 2 of the array; it sets the first two bytes of that slot to indicate that the VARIANT points to a string.

  5. Then it allocates space for a string containing "demonstration" and puts the address of that string into slot 3 of the array; it sets the first two bytes of that slot to indicate that the VARIANT points to a string.

Whew. Okay?

NOW...a quiz: In that code, what does the variable named ar look like in memory? Don't answer in haste. Think about it. Did you remember part 1 of this series? Did you remember paragraph 2 of this article? To quote: "all variables are always of the same kind or type."

Yes, even the variable ar is, of necessity, a VARIANT! And what do you suppose its particular VARIANT contains? Yep. Two bytes that say it is a pointer to an array and then, somewhere in the other 14 bytes, a pointer to the actual array!

So, in the next line of the code, above, we have the expression ar(3). And now we understand how it works! The VBScript language processor retrieves the contents of the variable ar. It looks at the VARIANT that is inevitably in those contents and notes that this particular variant is a pointer to an array. So it picks up the address of the array and remembers it. Then it sees the (3) as the element number [it would be an error if ar were not an array!], so it multiplies 3 times 16. It thus adds 48 to the array address it remembered to construct the address of element 3 of the array. Then it picks up the 16 bytes of memory that appear at the calculated address. Why 16 bytes? Because, again, every element of the array is a VARIANT. It looks at the VARIANT it thus got and sees that this is a string, so it extracts the address of the referenced string from the known spot in the VARIANT, uses that address to go fetch the actual string, and (finally!) it can Response.Write the string.

Wow! What a lot of work for a seemingly innocuous operation, right? Honest, this is incredibly simple compared to what must happen when VBScript calls a method on some ActiveX object. But let's not digress...

Now that we've looked at how VBScript handles single-dimensional arrays we should turn our attention to multi-dimensional arrays. In Part 2 of this article we will examine how multi-dimensional (specifically two-dimensional) arrays are internally managed by VBScript.

  • Read Part 2!


  • Article Information
    Article Title: Variables, Values, and Arrays in VBScript (Part 2 of a 3-Part Series)
    Article Author: Bill Wilkinson
    Published Date: Wednesday, April 11, 2001
    Article URL: http://www.4GuysFromRolla.com/webtech/041101-1.shtml


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers