vrm@blackwater.cerc.wvu.wvnet.edu (Vasile R. Montan) (04/03/91)
I want to have variable length arrays in Pascal. Pascal, however, does not want me to have variable length arrays in it. I think I've figured out a way to do this. This solution is probably glaringly obvious to more experienced programmers, but I want to run it past you to see if there's any reason why it shouldn't work. Suppose I define a type in Pascal which is an arbitrarily large array: say, one with 10000 elements in it, or some number larger than I will ever need. Suppose I then define a pointer to point to this type, and a handle to point to the pointer. Let's say I want to start out with seven elements in the array, so I use NewHandle and allocate just enough memory to hold those seven elements. I store this number seven in a variable to keep track of how big the array is. Now, as long as I am careful not to refer to any elements beyond the end of the memory block, I should not have any problems, right? And if I want to resize the array, I can use SetHandleSize, making sure to keep track of how many elements are now in the array, right? Is there any reason why this shouldn't work? --Kurisuto un020070@vaxa.wvnet.edu
russotto@eng.umd.edu (Matthew T. Russotto) (04/03/91)
In article <1521@babcock.cerc.wvu.wvnet.edu> un020070@vaxa.wvnet.edu writes: >I want to have variable length arrays in Pascal. Pascal, however, >does not want me to have variable length arrays in it. I think I've >figured out a way to do this. This solution is probably glaringly >obvious to more experienced programmers, but I want to run it >past you to see if there's any reason why it shouldn't work. > >Suppose I define a type in Pascal which is an arbitrarily large >array: say, one with 10000 elements in it, or some number larger than >I will ever need. Suppose I then define a pointer to point to >this type, and a handle to point to the pointer. Let's say I want >to start out with seven elements in the array, so I use NewHandle >and allocate just enough memory to hold those seven elements. I >store this number seven in a variable to keep track of how big >the array is. > >Now, as long as I am careful not to refer to any elements beyond the >end of the memory block, I should not have any problems, right? >And if I want to resize the array, I can use SetHandleSize, >making sure to keep track of how many elements are now in the array, >right? Is there any reason why this shouldn't work? I believe this is similiar to the way Apple does it for CTabHandles and other variable-length arrays. They declare theirs to be TYPE CSpecArray: Array [0..0] of ColorSpec; and turn off range checking so the references succeed. If you want range checking effective for other arrays, your method should work. -- Matthew T. Russotto russotto@eng.umd.edu russotto@wam.umd.edu .sig under construction, like the rest of this campus.
sundinKC@dna.lth.se (Anders Sundin) (04/03/91)
Kurisuto writes: > I want to have variable length arrays in Pascal. Pascal, however, > does not want me to have variable length arrays in it. I think I've > figured out a way to do this. This solution is probably glaringly > obvious to more experienced programmers, but I want to run it > past you to see if there's any reason why it shouldn't work. > > Suppose I define a type in Pascal which is an arbitrarily large > array: say, one with 10000 elements in it, or some number larger than > I will ever need. Suppose I then define a pointer to point to > this type, and a handle to point to the pointer. Let's say I want > to start out with seven elements in the array, so I use NewHandle > and allocate just enough memory to hold those seven elements. I > store this number seven in a variable to keep track of how big > the array is. > > Now, as long as I am careful not to refer to any elements beyond the > end of the memory block, I should not have any problems, right? > And if I want to resize the array, I can use SetHandleSize, > making sure to keep track of how many elements are now in the array, > right? Is there any reason why this shouldn't work? Here is how I do dynamic memory allocation in Pascal. data = record x : Real; y : Real; z : Real; end; arrHandle = ^arrPtr; arrPtr = ^arr; arr = array [1..MaxInt] of data; objHandle = ^objPtr; objPtr = ^obj; obj = record nData : Integer; nAlloc : Integer; dataH : arrHandle; nextObj : objHandle; end; function AllocObject(n: LongInt): objHandle; var theObj : objHandle; begin theObj := objHandle(NewHandle(SizeOf(obj))); if theObj <> nil then begin theObj^^.dataH := arrHandle(NewHandle(n * SizeOf(data))); if theObj^^.dataH = nil then begin DisposHandle( Handle(theObj)); theObj := nil; end else begin theObj^^.nData := 0; theObj^^.nAlloc := n; theObj^^.nextObj := nil; end; end; AllocObject := theObj; end; function ReallocObject(theObj: objHandle; n: LongInt): Boolean; begin SetHandleSize(Handle(theObj^^.dataH), n * SizeOf(data)); if MemError = noErr then begin theObj^^.nAlloc := n; if theObj^^.nData > n then theObj^^.nData := n; ReallocObject := true; end else ReallocObject := false; end; -- Anders Sundin e-mail: sundinKC@dna.lth.se Organic Chemistry 2, ok2aps@seldc52.bitnet P.O. Box 124 phone: +46 46 108214 S-22100 Lund, Sweden fax: +46 46 108209
jmatthews@desire.wright.edu (04/05/91)
In article <1521@babcock.cerc.wvu.wvnet.edu>, vrm@blackwater.cerc.wvu.wvnet.edu (Vasile R. Montan) writes: > I want to have variable length arrays in Pascal. Pascal, however, > does not want me to have variable length arrays in it. I think I've > figured out a way to do this. > ... > Suppose I define a type in Pascal which is an arbitrarily large > array: say, one with 10000 elements in it, or some number larger than > I will ever need. Suppose I then define a pointer to point to > this type, and a handle to point to the pointer. Let's say I want > to start out with seven elements in the array, so I use NewHandle > and allocate just enough memory to hold those seven elements. I > store this number seven in a variable to keep track of how big > the array is. > > Now, as long as I am careful not to refer to any elements beyond the > end of the memory block, I should not have any problems, right? > And if I want to resize the array, I can use SetHandleSize, > making sure to keep track of how many elements are now in the array, > right? Is there any reason why this shouldn't work? > > --Kurisuto > un020070@vaxa.wvnet.edu Your technique is sound. I think that's how TextEdit's lineStarts array and the List Manager's cellArray work. Notice that only the lower array bound matters: it determines whether the array starts with element 0 or 1. The upper bound is immaterial since you'll never create an instance variable of this type, only a pointer to it. Moreover, you can keep the count with the array Type MyArray = record count:Integer; elements: array[1..1] of MyArrayElemnt end; Finally, I recently "discovered" the ToolBox Utility PtrAndHand. It's great in this context since it does the GetHandleSize, SetHandleSize and BlockMove stuff you'ld have to do yourself. You can always get a Ptr to the source data with the @ operator and the destination handle can be unlocked (PtrAndHand does the right thing internally, I think:-). Hope this helps, John o----------------------------------------------------------------------------o | John B. Matthews, jmatthews@desire.wright.edu, am103@cleveland.freenet.edu | | "Say...what's a mountain goat doing way up here in a cloud bank?" - Larson | o----------------------------------------------------------------------------o
phils@chaos.cs.brandeis.edu (Phil Shapiro) (04/12/91)
In article <1991Apr4.124257.3095@desire.wright.edu> jmatthews@desire.wright.edu writes: In article <1521@babcock.cerc.wvu.wvnet.edu>, vrm@blackwater.cerc.wvu.wvnet.edu (Vasile R. Montan) writes: > I want to have variable length arrays in Pascal. Pascal, however, > does not want me to have variable length arrays in it. I think I've > figured out a way to do this. > ... > Suppose I define a type in Pascal which is an arbitrarily large > array: say, one with 10000 elements in it, or some number larger than > I will ever need. Suppose I then define a pointer to point to > this type, and a handle to point to the pointer. Let's say I want > to start out with seven elements in the array, so I use NewHandle > and allocate just enough memory to hold those seven elements. I > store this number seven in a variable to keep track of how big > the array is. Your technique is sound. I think that's how TextEdit's lineStarts array and the List Manager's cellArray work. Notice that only the lower array bound matters: it determines whether the array starts with element 0 or 1. The upper bound is immaterial since you'll never create an instance variable of this type, only a pointer to it. Moreover, you can keep the count with the array Type MyArray = record count:Integer; elements: array[1..1] of MyArrayElemnt end; I don't know about MPW Pascal, but THINK Pascal make some assumptions about how an array is indexed depending on its upper bound (really, the range over which it is bound). If you want to use the SetHandleSize method to expand/shrink an array, make sure that you dimension your array as the largest possible array that you're planning to resize it to. If you don't use this method, your programs will surely crash. -phil
mitch@Apple.COM (Mitchell Adler) (04/17/91)
In article <1521@babcock.cerc.wvu.wvnet.edu> un020070@vaxa.wvnet.edu writes: >I want to have variable length arrays in Pascal. [Reason for having variable length arrays deleted] >Suppose I define a type in Pascal which is an arbitrarily large >array: say, one with 10000 elements in it, or some number larger than >I will ever need. Suppose I then define a pointer to point to >this type, and a handle to point to the pointer. Let's say I want >to start out with seven elements in the array, so I use NewHandle >and allocate just enough memory to hold those seven elements. I >store this number seven in a variable to keep track of how big >the array is. > >Now, as long as I am careful not to refer to any elements beyond the >end of the memory block, I should not have any problems, right? >And if I want to resize the array, I can use SetHandleSize, >making sure to keep track of how many elements are now in the array, >right? Is there any reason why this shouldn't work? Umm..not quite. Pascal is defined to Range Check at RUN time. That is, if you access outside of the declared range it's a runtime error. So as long as your dynamic array is smaller than your declared array, you'd be OK for the range checking (assuming you don't write outside the actual size of the array, as you said). But if you ever tried to write to a location beyond the end of your declared size, you'd get a runtime error. MPW Pascal (and I believe Think Pascal also), have the ability to turn off runtime range checking. You'll need to turn it off everywhere you index into your dynamic array. In MPW Pascal you use the directive: {$R-} to turn runtime range checking for sets, arrays and strings off. {$R+} to turn it back on. >--Kurisuto >un020070@vaxa.wvnet.edu Mitch -- Mitch Adler mitch@apple.com Development Systems Apple Computer, Inc. AppleLink: M.Adler Claimer: These are MY opinions, not Darin's, not Apple's! MINE!
vrm@babcock.cerc.wvu.wvnet.edu (Vasile R. Montan) (04/21/91)
From article <13102@goofy.Apple.COM>, by mitch@Apple.COM (Mitchell Adler): [Deleted posting in which I ask whether you can SetHandleSize on an array as long as you're careful not to read/write past the end of the block] > Umm..not quite. Pascal is defined to Range Check at RUN time. That is, > if you access outside of the declared range it's a runtime error. So > as long as your dynamic array is smaller than your declared array, > you'd be OK for the range checking (assuming you don't write outside > the actual size of the array, as you said). But if you ever tried to > write to a location beyond the end of your declared size, you'd get a > runtime error. > > MPW Pascal (and I believe Think Pascal also), have the ability to turn off > runtime range checking. You'll need to turn it off everywhere you index > into your dynamic array. I've gone ahead and used the technique, but I am running into a problem of a different kind. I'd like to be able to define an array as, say, MyArrayType = array[0..32000] of SomeType, since 32000 is a lot bigger than I will ever need. Unfortunately, the Lightspeed Pascal Compiler (which is what I'm stuck with) gives it a thumbs-down and says "Variables of this type would be too large." It seems the biggest range possible is around [0..125], which may not be big enough for what I need. Don't some versions of Pascal allow you to declare a range as [0..0] to solve this problem? Lightspeed takes this to mean that your array has only one element, number 0, and gives a range error if you refer, say, number 1. So how do I turn off range checking in Lightspeed Pascal? Any ideas? --Kurisuto un020070@vaxa.wvnet.edu
unierik@uts.uni-c.dk (Erik Bertelsen) (04/22/91)
> In MPW Pascal you use the directive: > {$R-} to turn runtime range checking for sets, arrays and strings off. > {$R+} to turn it back on. You can even do this: {$push}{$R-} { some code that is performed without runtime range checks } {$pop} { resume previous setting } This will allow you preserve the global setting of range check (and other options) and have the global setting be one value while debugging and another in final builds. regards Erik Bertelsen UNI-C, The Danish Computing Centre for Research and Education.