Re: [fpc-pascal] 2D Dynamic arrays and BlockRead
STat = Array[0..W-1] Of Single ; { Static array } DST = Array Of STat ; { One dimension dynamic, the other static } D2T = Array Of Array Of Single ; { Two dynamic dimensions } STat always means the address starting with STat[0] (context independend). Also DST always means the address where DST[0]. Nope, there is a difference between DST and DST[0]. DST won't give you the first element. Yes, you are right. I missread the definition. What I had in mind was that the first level of the array being static and only the second one dynamic but actualy it was vice versa. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] 2D Dynamic arrays and BlockRead
On 12/7/2010 12:37 PM, andrew.benn...@ns.sympatico.ca wrote: In various places, "dynamic array" becomes "dynamical array" which messes up searching. Somebody should decide which it is! Dynamical is inappropriate usage in this context. Dynamic is correct. -- Rich S. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] 2D Dynamic arrays and BlockRead
Marc Weustink wrote >On 3-12-2010 17:26, Jürgen Hestermann wrote: >> ... >> STat = Array[0..W-1] Of Single ; { Static array } >> DST = Array Of STat ; { One dimension dynamic, the other static } >> D2T = Array Of Array Of Single ; { Two dynamic dimensions } >> >> STat always means the address starting with STat[0] (context independend). >> Also DST always means the address where DST[0]. > >Nope, there is a difference between DST and DST[0]. DST won't give you >the first element. You can try this youself with an untyped parameter: > >procedure Foo(const AParam); >begin > WriteLN(Single(APAram)); >end; > > >You will see a difference between passing DST or DST[0] >To be safe, for any N-dimension dynamic array always use [0,..,0] to >pass the first element. To avoid confusion, you can do this for static >arrays too. Thanks. I've now got things working. More or less. But where do I find any of this in the documentation? Ref 3.3.1 gives an example of a 2-D dynamic array that looks just like a static array apart from the difference in copying: no mention of the dramatic low-level differencess. But then, these differences are part of the implementation so perhaps they should be in the Programmers' Manual. They aren't. The Ref example uses the 2-D form of Setlength which is not to be found in RTL 37.9.309. Complexities are hinted at in RTL 37.9.52, DynArraySetLength but I am very happy to heed the warning not to mess with that! Ref 3.3.1 states that memory for a dynamic array will be disposed of at the exit of the procedure or function. Um! In various places, "dynamic array" becomes "dynamical array" which messes up searching. Somebody should decide which it is! Andrew Bennett ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] 2D Dynamic arrays and BlockRead
On 3-12-2010 17:26, Jürgen Hestermann wrote: andrew.benn...@ns.sympatico.ca schrieb: After using BlockRead to fill a 2D dynamic array, I get an access violation on the very first reference. A 2D array with only one dimension dynamic works OK. What am I missing? Maybe you blundered into the same trap as so many others who do not know that dynamic arrays are *pointers* (to arrays). It is one of the sins done by Borland to abandon the once strict logic that in Pascal the syntax is always context independend. Now this is no longer the case (i.e. for dynamic arrays). in your example STat = Array[0..W-1] Of Single ; { Static array } DST = Array Of STat ; { One dimension dynamic, the other static } D2T = Array Of Array Of Single ; { Two dynamic dimensions } STat always means the address starting with STat[0] (context independend). Also DST always means the address where DST[0]. Nope, there is a difference between DST and DST[0]. DST won't give you the first element. You can try this youself with an untyped parameter: procedure Foo(const AParam); begin WriteLN(Single(APAram)); end; You will see a difference between passing DST or DST[0] To be safe, for any N-dimension dynamic array always use [0,..,0] to pass the first element. To avoid confusion, you can do this for static arrays too. But D2T is a pointer which can be either the the address of the pointer (in all low level routines like fillchar, sizeof, BlockRead/-Write etc.) but also can be the address of the D2T[0] because you can refer to elements without the need to dereference it as in D2T^[0]. In behaviour DST and D2T wont differ. Marc ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] 2D Dynamic arrays and BlockRead
On 05/12/2010 23:35, andrew.benn...@ns.sympatico.ca wrote: J?rgen Hestermann wrote andrew.benn...@ns.sympatico.ca schrieb: After using BlockRead to fill a 2D dynamic array, I get an access violation on the very first reference. A 2D array with only one dimension dynamic works OK. What am I missing? Maybe you blundered into the same trap as so many others who do not know that dynamic arrays are *pointers* (to arrays). It is one of the sins done by Borland to abandon the once strict logic that in Pascal the syntax is always context independend. Now this is no longer the case (i.e. for dynamic arrays). After wasting another 2 days reading the documentation, I returned to blind experiment ... I find that BlockRead(F, A[J,0], RightDim*Sizeof(Single), count) works where BlockRead(F, A[J], RightDim*Sizeof(Single), count) does not. That is, reading RightDim elements into a space the size of one element is OK but reading them into a space of the correct size is not. Personally, I would call that a BUG. No, a feature. I guess you assume that an array "a array of array of integer" is a continuous block in memory. But it is not type TIntArray: array of integer; var a1: TIntArray; makes "a1" a *pointer* to a block of memory var a2: array of TIntArray; makes a2 a pointer to a list of pointers, each of them pointing to a further block of memory. BlockRead(F, A[J], ) overwrites the pointers, pointing to the 2nd dimension arrays. BTW, it actually is not just a pointer, but a refcounted pointer. so after BlockRead(F, A[J], ); not only do the pointer point to random location, the whole refcounting is messed up too. Martin ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] 2D Dynamic arrays and BlockRead
J?rgen Hestermann wrote >andrew.benn...@ns.sympatico.ca schrieb: >> After using BlockRead to fill a 2D dynamic array, I get an access >>violation on the very first reference. A 2D array with only one >>dimension dynamic works OK. What am I missing? > >Maybe you blundered into the same trap as so many others who do not know >that dynamic arrays are *pointers* (to arrays). It is one of the sins >done by Borland to abandon the once strict logic that in Pascal the >syntax is always context independend. Now this is no longer the case >(i.e. for dynamic arrays). After wasting another 2 days reading the documentation, I returned to blind experiment ... I find that BlockRead(F, A[J,0], RightDim*Sizeof(Single), count) works where BlockRead(F, A[J], RightDim*Sizeof(Single), count) does not. That is, reading RightDim elements into a space the size of one element is OK but reading them into a space of the correct size is not. Personally, I would call that a BUG. Andrew Bennett ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] 2D Dynamic arrays and BlockRead
andrew.benn...@ns.sympatico.ca schrieb: After using BlockRead to fill a 2D dynamic array, I get an access violation on the very first reference. A 2D array with only one dimension dynamic works OK. What am I missing? Maybe you blundered into the same trap as so many others who do not know that dynamic arrays are *pointers* (to arrays). It is one of the sins done by Borland to abandon the once strict logic that in Pascal the syntax is always context independend. Now this is no longer the case (i.e. for dynamic arrays). in your example STat = Array[0..W-1] Of Single ; { Static array } DST = Array Of STat ; { One dimension dynamic, the other static } D2T = Array Of Array Of Single ; { Two dynamic dimensions } STat always means the address starting with STat[0] (context independend). Also DST always means the address where DST[0]. But D2T is a pointer which can be either the the address of the pointer (in all low level routines like fillchar, sizeof, BlockRead/-Write etc.) but also can be the address of the D2T[0] because you can refer to elements without the need to dereference it as in D2T^[0]. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] 2D Dynamic arrays and BlockRead
After using BlockRead to fill a 2D dynamic array, I get an access violation on the very first reference. A 2D array with only one dimension dynamic works OK. What am I missing? Windows, FPC 2.2.2, 2.2.4 or 2.4.2. Program WriteA ; { Write a binary file using using static array and BlockWrite } Const W = 2 ; H = 2 ; FName = 'C:\FPC\2.2.2\USR\GASH.BIN' ; Type A2T = Array[0..H-1,0..W-1] Of Single ; Var D : A2T ; F : File ; J, C : Longint ; Begin D[0,0] := 1 ; D[0,1] := 2 ; D[1,0] := 3 ; D[1,1] := 4 ; Assign(F, FName) ; Rewrite(F, 1) ; For J := 0 To H-1 Do Blockwrite(F, D[J], W*Sizeof(Single), C) ; Close(F) ; Writeln(D[0,0]:2:0, #9, D[0,1]:2:0, #9, D[1,0]:2:0, #9, D[1,1]:2:0) ; End. Program DynRd ; { Read binary file written by "WriteA" } Const W = 2 ; H = 2 ; FName = 'C:\FPC\2.2.2\USR\GASH.BIN' ; Type STat = Array[0..W-1] Of Single ; { Static array } DST = Array Of STat ; { One dimension dynamic, the other static } D2T = Array Of Array Of Single ; { Two dynamic dimensions } Var DD : D2T ; DS : DST ; F : File ; J, C : Longint ; Begin SetLength(DS, H) ; { Test mixed array } Assign(F, FName) ; Reset(F, 1) ; For J := 0 To H-1 Do Begin BlockRead(F, DS[J], W*Sizeof(Single), C) ; If (C <> W*Sizeof(Single)) Then Writeln('Oops at J = ', J) ; End ; Close(F) ; Writeln(DS[0,0]:2:0, #9, DS[0,1]:2:0, #9, DS[1,0]:2:0, #9, DS[1,1]:2:0, #9'Should be 1, 2, 3, 4') ; { This works } SetLength(DS, 0) ; SetLength(DD, H, W) ; { Test 2D dynamic array } Assign(F, FName) ; Reset(F, 1) ; For J := 0 To H-1 Do Begin BlockRead(F, DD[J], W*Sizeof(Single), C) ; If (C <> W*Sizeof(Single)) Then Writeln('Oops at J = ', J) ; End ; Close(F) ; Writeln(DD[0,0]:2:0, #9, DD[0,1]:2:0, #9, DD[1,0]:2:0, #9, DD[1,1]:2:0, #9'Should also be 1, 2, 3, 4') ; { Quits, error 216, reading DD[0,0] } SetLength(DD, 0, 0) ; End. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal