Recent

Author Topic: program locks up using setlength(array,n) on Packed Array of byte  (Read 3057 times)

dieselnutjob

  • Full Member
  • ***
  • Posts: 224
Hi
I have a program that's locking up (this bit of code is buried deep in a thread so I don't exactly know how) when I invoke setlength on a variable length array.
The definition is:-
ABlock: Packet Array of byte;
Previously in the code the length is set to zero.
When I do setlength(ABlock,n) it locks up, and if I remove that one line, it doesn't.
It seems to be specific to fpc 3.0.4 an MacOS
Anyone got any ideas why?
thanks

PascalDragon

  • Hero Member
  • *****
  • Posts: 5769
  • Compiler Developer
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #1 on: June 06, 2023, 09:47:55 pm »
Without more code it's hard to tell. Can the variable be accessed from different threads at the same time?

dieselnutjob

  • Full Member
  • ***
  • Posts: 224
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #2 on: June 07, 2023, 12:06:50 am »
The array is only touched in the one thread.

440bx

  • Hero Member
  • *****
  • Posts: 4761
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #3 on: June 07, 2023, 12:15:59 am »
Is ABlock in a "var" section or in a "const" section ?

if it happens to be in a "const" section that might be the cause.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

dieselnutjob

  • Full Member
  • ***
  • Posts: 224
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #4 on: June 07, 2023, 12:19:57 am »
it's in a var section immediately after "implementation"

dieselnutjob

  • Full Member
  • ***
  • Posts: 224
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #5 on: June 07, 2023, 12:26:40 am »
aah

It's not a var inside any function, and all the functions belong to a class(object) thing.
So I suppose that vars are immediately after "implementation" belong to the unit but not the object?
Maybe that doesn't matter if they are fixed length but maybe it does matter if they are variable length?
Because a function in an object is changing the length of a thing that's not part of the object?
Could that be it or am I talking rubbish?

440bx

  • Hero Member
  • *****
  • Posts: 4761
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #6 on: June 07, 2023, 08:29:33 am »
Could that be it or am I talking rubbish?
Without seeing the code, it's really difficult to say. 

The reason I mentioned "const" vs "var" is because if the dynamically sized array is in a read-only const section then a SetLength would cause an exception (the pointer that identifies/references the array cannot be assigned a value because it cannot be written to.)

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

TRon

  • Hero Member
  • *****
  • Posts: 3660
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #7 on: June 07, 2023, 09:12:52 am »
Could that be it or am I talking rubbish?
Without seeing the code, it's really difficult to say. 
+1

Everything in the implementation section (not part of an/the thread object/class) is part of the main thread. If you create another thread that access such declarations then you have multiple threads accessing a single variable. Using setlength implies that there needs to be memory allocated (amongst others) and since you are doing that from the 'other' thread (not mainthread) that could lead to issues.

There even is a terminology for that named threadsafe (programming).

This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

PascalDragon

  • Hero Member
  • *****
  • Posts: 5769
  • Compiler Developer
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #8 on: June 08, 2023, 12:53:47 pm »
It's not a var inside any function, and all the functions belong to a class(object) thing.

That's an important difference.

So I suppose that vars are immediately after "implementation" belong to the unit but not the object?

Correct.

Maybe that doesn't matter if they are fixed length but maybe it does matter if they are variable length?

If you modify the contents even if the length stays the same then it always does matter if it might be accessed from multiple threads.

cdbc

  • Hero Member
  • *****
  • Posts: 1678
    • http://www.cdbc.dk
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #9 on: June 08, 2023, 04:05:44 pm »
Hi
You've piqued my interest... So here goes, attached is a small class and interface, to be used in multithreaded access to a "packed array of byte".
If it can be of use to you, then I've got a quick'n'dirty use-example...
Code: Pascal  [Select][+][-]
  1. uses ..., u_clspab, u_intfpab;
  2. var
  3.   s: shortstring;
  4.   cls: TThreadsafePackedArrayOfByte;
  5.   pab: IThreadsafePackedArrayOfByte;
  6. {$region pab}
  7. function NewArray(aSize: ptruint): IThreadsafePackedArrayOfByte;
  8. begin
  9.   cls:= TThreadsafePackedArrayOfByte.Create(aSize);
  10.   if not cls.GetInterface(SGUIDIThreadsafePackedArrayOfByte,Result) then Result:= nil;
  11. end;
  12. procedure DisposeArray; begin FreeAndNil(cls); pab:= nil; end;
  13. procedure WriteArray(aBuf: IThreadsafePackedArrayOfByte);
  14. var a: TPAoB; s: string;
  15. begin
  16.   a:= aBuf.LockArray;
  17.   try
  18.     SetLength(s,Length(a));
  19.     move(a[0],s[1],Length(a));
  20.     writeln('*) Array of byte: ',s);
  21.     s:= ''
  22.   finally aBuf.UnLockArray; end;
  23. end;
  24. {$endregion pab}
  25. ...
  26.   S:= 'Lyserøde GyngehesteRøvhuller til salg';
  27.   pab:= NewArray(Length(S));
  28.   try
  29.     move(S[1],pab.LockArray[0],Length(S));
  30.     pab.UnLockArray; { !!! very important !!! as we use it without try...finally}
  31.     WriteArray(pab);
  32.     pab.SetSize(0);
  33.   finally DisposeArray; end;
  34.   writeln('Done!');
  35. /// NB.: if you change the interface to com and "TObject" to ///
  36. ///  "TInterfacedObject", you can do it like this: ///
  37. //  pab:= TThreadsafePackedArrayOfByte.Create(Length(S));
  38. //  ... use pab
  39. //  pab:= nil; // refcounting frees it
  40.  
Let me know what you think...
Regards Benny
« Last Edit: June 09, 2023, 12:25:26 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

dieselnutjob

  • Full Member
  • ***
  • Posts: 224
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #10 on: June 09, 2023, 12:31:35 am »
I got my code to work today (before reading cbdb's reply).

I got it to work by changing the variable length array to a fixed length one, and now it all works.

I have other functions in other parts of the code that use variable length arrays, and they work, but there is one crucial difference which is that these array are defined inside the function that touches the array.

So it seems to me that with 3.0.4 on MacOS that:-
You can have a fixed length array in the var section after implementation, before all the functions, so accessible to all functions.
or
You can have a variable length array in the var section of just the function that uses it.

If you want a variable length array that's accessed by multiple functions (even if they are in the same thread) then it seems to be a problem (but only in MacOS).

cdbc

  • Hero Member
  • *****
  • Posts: 1678
    • http://www.cdbc.dk
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #11 on: June 09, 2023, 09:34:10 am »
Hi
Good on you  :D
I seem to remember, I once had an issue with dynamic arrays, they would crash if I didn't initialize them, with just one byte on creation, so that they were not nil, when I needed them... You might need input on this from @PascalDragon or colleagues, as I think it's above my paygrade  ;D
That's also why I used this: "fPAB:= [];" construct, in my class' constructor, as that seems to be dabbling as "constructor" for dynamic arrays.
Anyway, great that you got it to work  8)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

dieselnutjob

  • Full Member
  • ***
  • Posts: 224
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #12 on: June 09, 2023, 02:51:43 pm »
the wiki page https://wiki.freepascal.org/Dynamic_array
mentions initialising, but I got the impression that it was optional.
so for an empty array should I be doing myarray.create();
?

cdbc

  • Hero Member
  • *****
  • Posts: 1678
    • http://www.cdbc.dk
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #13 on: June 09, 2023, 04:44:55 pm »
Hi
I've just read the wiki too, and yes there are "more ways to skin that cat".
- The object oriented way: with .Create(0,1,2,3); // from wiki
- The subtle way: iArray:= [7, 8, 9]; // from wiki
- The declaration way: iArray: array of byte = (4,5,6); // from wiki
I find the [] subtle way leans itself more towards array-syntaks, as I know it, easier on the eye, if you will  ;) I guess it comes down to preference and size of dataset...
Mind you, I'll just check the fpc-reference now...
edit: According to the reference, all 3 are valid from version 3.2 and upwards.  8-)
Regards Benny
« Last Edit: June 09, 2023, 04:55:27 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

PascalDragon

  • Hero Member
  • *****
  • Posts: 5769
  • Compiler Developer
Re: program locks up using setlength(array,n) on Packed Array of byte
« Reply #14 on: June 09, 2023, 10:15:10 pm »
If you want a variable length array that's accessed by multiple functions (even if they are in the same thread) then it seems to be a problem (but only in MacOS).

Doubtful. But without explicit source code it's hard to tell what you're doing wrong.

 

TinyPortal © 2005-2018