Beware dynamic array sizing. This caught me out ...
PROGRAM dyn_arr_test(input,output);
CONST a = 3; b = 10;
TYPE Dyn_arr( Max_index : INTEGER ) = ARRAY [1..Max_index] OF INTEGER; Ptr_to_dyn_arr = ^Dyn_arr;
VAR Test1 : Ptr_to_dyn_arr; Test2 : Ptr_to_dyn_arr; Test1a : ARRAY [1..3] OF INTEGER; Test2a : ARRAY [1..10] OF INTEGER;
PROCEDURE zero(VAR param; ch : char; size : longint); asmname 'memset';
BEGIN NEW( Test1, a ); writeln(sizeof(Test1^)); zero(Test1^,#0,sizeof(Test1^)); NEW( Test2, b ); writeln(sizeof(Test2^)); zero(Test2^,#0,sizeof(Test2^));
writeln(sizeof(Test1a)); zero(Test1a,#0,sizeof(Test1a)); writeln(sizeof(Test2a)); zero(Test2a,#0,sizeof(Test2a)); END.
The results are 16 and 44 for the dynamic arrays, 12 and 40 for the non-dynamic arrays. ie. the 'sizeof' function returns an additional 4 words for the dynamic arrays and so my zero function was overwriting memory beyond the dynamic array boundaries.
Is this an unavoidable feature, a compiler bug or to be completely expected?
I am assuming the 'new' function doesn't explicitly zero memory and so I need to do. I have used this zero function on all the usual Pascal variables without problem, but I suspect it has a strange effect when used to zero a record containing a string. Can anyone confirm whether there are particular Pascal structures that shouldn't be zeroed by this technique (apart from dynamic arrays)?
Regards
David Wood QinetiQ, Farnborough
The Information contained in this E-Mail and any subsequent correspondence is private and is intended solely for the intended recipient(s). For those other than the recipient any disclosure, copying, distribution, or any action taken or omitted to be taken in reliance on such information is prohibited and may be unlawful.
Don't you think the problem is in using a recursive function to zero arrays instead of a simple for-end cycle?
Bye
Silvio
| > Beware dynamic array sizing. This caught me out ... | > | > PROGRAM dyn_arr_test(input,output); | > | > CONST | > a = 3; | > b = 10; | > | > TYPE | > Dyn_arr( Max_index : INTEGER ) = ARRAY [1..Max_index] OF INTEGER; | > Ptr_to_dyn_arr = ^Dyn_arr; | > | > VAR | > Test1 : Ptr_to_dyn_arr; | > Test2 : Ptr_to_dyn_arr; | > Test1a : ARRAY [1..3] OF INTEGER; | > Test2a : ARRAY [1..10] OF INTEGER; | > | > PROCEDURE zero(VAR param; ch : char; size : longint); asmname 'memset'; | > | > BEGIN | > NEW( Test1, a ); | > writeln(sizeof(Test1^)); | > zero(Test1^,#0,sizeof(Test1^)); | > NEW( Test2, b ); | > writeln(sizeof(Test2^)); | > zero(Test2^,#0,sizeof(Test2^)); | > | > writeln(sizeof(Test1a)); | > zero(Test1a,#0,sizeof(Test1a)); | > writeln(sizeof(Test2a)); | > zero(Test2a,#0,sizeof(Test2a)); | > END. | > | > The results are 16 and 44 for the dynamic arrays, 12 and 40 for the | > non-dynamic arrays. | > ie. the 'sizeof' function returns an additional 4 words for the dynamic | > arrays and so my zero function was overwriting memory beyond the dynamic | > array boundaries. | > | > Is this an unavoidable feature, a compiler bug or to be completely | > expected? | > | > I am assuming the 'new' function doesn't explicitly zero memory and so I | > need to do. I have used this zero function on all the usual Pascal | > variables without problem, but I suspect it has a strange effect when | > used to zero a record containing a string. Can anyone confirm whether | > there are particular Pascal structures that shouldn't be zeroed by this | > technique (apart from dynamic arrays)? | > | > Regards | > | > David Wood | > QinetiQ, Farnborough |
Wood David a écrit:
Beware dynamic array sizing. This caught me out ...
PROGRAM dyn_arr_test(input,output);
CONST a = 3; b = 10;
TYPE Dyn_arr( Max_index : INTEGER ) = ARRAY [1..Max_index] OF INTEGER; Ptr_to_dyn_arr = ^Dyn_arr;
VAR Test1 : Ptr_to_dyn_arr; Test2 : Ptr_to_dyn_arr; Test1a : ARRAY [1..3] OF INTEGER; Test2a : ARRAY [1..10] OF INTEGER;
PROCEDURE zero(VAR param; ch : char; size : longint); asmname 'memset';
BEGIN NEW( Test1, a ); writeln(sizeof(Test1^)); zero(Test1^,#0,sizeof(Test1^)); NEW( Test2, b ); writeln(sizeof(Test2^)); zero(Test2^,#0,sizeof(Test2^));
writeln(sizeof(Test1a)); zero(Test1a,#0,sizeof(Test1a)); writeln(sizeof(Test2a)); zero(Test2a,#0,sizeof(Test2a)); END.
The results are 16 and 44 for the dynamic arrays, 12 and 40 for the non-dynamic arrays. ie. the 'sizeof' function returns an additional 4 words for the dynamic arrays and so my zero function was overwriting memory beyond the dynamic array boundaries.
Is this an unavoidable feature, a compiler bug or to be completely expected?
Completely expected, the dynamic array size has to be somewhere in the structure at run time. For static arrays only the compiler has to know.
I am assuming the 'new' function doesn't explicitly zero memory and so I need to do. I have used this zero function on all the usual Pascal variables without problem, but I suspect it has a strange effect when used to zero a record containing a string. Can anyone confirm whether there are particular Pascal structures that shouldn't be zeroed by this technique (apart from dynamic arrays)?
Any kind of schemata, which include dynamic arrays ans strings
Maurice
Maurice Lombardi wrote:
I am assuming the 'new' function doesn't explicitly zero memory and so I need to do. I have used this zero function on all the usual Pascal variables without problem, but I suspect it has a strange effect when used to zero a record containing a string. Can anyone confirm whether there are particular Pascal structures that shouldn't be zeroed by this technique (apart from dynamic arrays)?
Any kind of schemata, which include dynamic arrays ans strings
Also files and objects.
There is a built-in procedure `Initialize' to (re-)initialize any variable, so you could theoretically zero out everything, then initialize it again, but I'm not sure if I should have mentioned this. ;-) In any case, you'll do some extra work (init, zero, init again) ...
Silvio a Beccara wrote:
Don't you think the problem is in using a recursive function to zero arrays instead of a simple for-end cycle?
It's not recursive. `asmname' implies external (at least for now ...). (And, BTW, this procedure is equivalent to the built-in `FillChar', except for the order of arguments.)
But I agree, in this case I'd recommend a `for' loop, too.
| > PROCEDURE zero(VAR param; ch : char; size : longint); asmname 'memset'; | > | > BEGIN | > NEW( Test1, a ); | > writeln(sizeof(Test1^)); | > zero(Test1^,#0,sizeof(Test1^)); | > NEW( Test2, b ); | > writeln(sizeof(Test2^)); | > zero(Test2^,#0,sizeof(Test2^)); | > | > writeln(sizeof(Test1a)); | > zero(Test1a,#0,sizeof(Test1a)); | > writeln(sizeof(Test2a)); | > zero(Test2a,#0,sizeof(Test2a)); | > END.
Frank