Should array's length be set to zero after use? - arrays

I'm wondering if setting Delphi's array's length to 0 after use is a correct practice or not.
var
MyArray : array of TObject;
begin
SetLength(MyArray, N);
// do something with MyArray (add items and use it..)
SetLength(MyArray, 0);
end;
Is there a reason why I should set length to 0?

Assuming that MyArray is a local variable then there is no reason at all to finalise the variable in the code presented. As soon as the variable leaves scope, it will be finalised. There's nothing to be gained by doing so explicitly.
Sometimes however, you have a variable whose scope extends significantly longer than your use of the array. In those scenarios it can be useful to finalise the variable as soon as you have finished with it so that the memory is returned.
Personally I would prefer
MyArray := nil;
or
Finalize(MyArray);
which in my opinion more readily jump out as finalisation statements. Your
SetLength(MyArray, 0);
can look like you are allocating when skimming the code.

Dynamic arrays are automatically freed when nothing is referencing it.
I would prefer the following method if you need to do this manually. This looks clear to me than other methods.
MyDynamicArray = nil;
It sets the natural environment of zero reference and let the memory manager to free it in due course.

Related

Kotlin/Native: Is CValue<T>.useContents dangerous?

In this paragraph it states that useContents "temporarily places the CValue to memory, and then runs the passed lambda with this placed value T as receiver".
A few questions about this:
Since this implies that T is not in memory at this moment, is there a risk that useContents fails because the value no longer available?
What happens if I do this: val foo = bar.useContents { this }. Does this copy T? Is it now in memory permanently? Do I need to clean it up manually somehow?
Why is this even necessary? Can't the compiler take care of these details? I just end up writing a lot of extension functions to hide useContents.

When to use slice instead of an array in GO

I am learning GO. According to documentation, slices are richer than arrays.
However, I am failing to grasp hypothetical use cases for slices.
What would be use case where one would use a slice instead of array?
Thanks!
This is really pretty elementary and probably should already have been covered in whatever documentation you're reading (unless it's just the language spec), but: A Go array always has a fixed size. If you always need 10 things of type T, [10]T is fine. But what if you need a variable number of things n, where n is determined at runtime?
A Go slice—which consists of two parts, a slice header and an underlying backing array—is pretty ideal for holding information needed to access a variable-sized array. Note that just declaring a slice-header variable:
var x []T
doesn't actually allocate any array of T yet: the slice header will be initialized to hold nil (converted to the right type) as the (missing) backing array, 0 as the current size, and 0 as the capacity of this array. As a result of this, the test x == nil will say that yes, x is nil. To get an actual array, you will need either:
an actual array, or
a call to make, or
use of the built-in append or similar (e.g., copy, append hidden behind some function, etc).
Since the call to make happens at runtime, it can make an array of whatever size is needed at this point. A series of calls to append can build up an array. Note that each call to append may have to allocate a new backing array, or may be able to extend the existing array in-place, depending on what's in the capacity. That's why you need x = append(x, elem) or x = append(x, elems...) and not just append(x, elem) or append(x, elems...).
The Go blog entry on slices has a lot more to say on this. I like this page more than the sequence of pages in the Go Tour starting here, but opinions vary.

Convert array to array of const in Delphi

I am looking for a simple and ideally general (or using generics) way to convert an array to an array of const (=array of TVarRec). My specific case is that I have an array of Variant and want to pass it to the Format() function.
This is what I've found so far, but it looks hackish to me:
function MyFormat(const Fmt: string; const Args: TArray<Variant>): string;
var
A: array of TVarRec;
I: Integer;
begin
SetLength(A, Length(Args));
for I:= Low(Args) to High(Args) do begin
A[I].VType:= vtVariant;
A[I].VVariant:= #Args[I];
end;
Result:= Format(Fmt, A);
end;
It seems to work. Is it safe?
Could it be done shorter, better, faster, or can I use something ready instead? :)
Just some additional thoughts and fun facts:
System.Rtti.TValue recently became my friend. However, it seems it is missing a feature here. I am able to read my array using TValue.From(), but it seems there is no way to get it out as array of TVarRec. There is a wonderful TValueArrayToArrayOfConst, but it doesn't really help, because I had to construct an array of TValue first, which is different from an array stored in a single TValue... :(
At least TValue is able to output a single element as TVarRec, so I thought I could create a generic converter for all types of arrays. But...
Would you think this works?
for I:= Low(Args) to High(Args) do A[I]:= TValue.From(Args[I]).AsVarRec;
It compiles, but TValue's memory is released after use, and since TVarRec.VVariant is a pointer, it then points to some old location which is overridden on next cycle.
Your function is safe and fast. It only allocates a small memory array A[], and passes all values by reference. I can't think on anything faster - without being premature optimization. I may only do some refactoring to reuse the TArray<variant> into TArray<TVarRec> conversion routine.
Using TValue.From().AsVarRec will definitively be slower, if your input is indeed a TArray<Variant>.
About TVarRec dandling references, you are right: those structures are just simple pointers on the stack, with no allocation, so all the referred variables should be available during the function call. So if you use a TArray<TVarRec> local conversion, you should ensure that the TArray<variant> is still allocated when calling the format() function.
A straight forward and short solution (in code). If your formatstring (fmt) and array of values (sa) are unknown.
setlength(sa,5); // or more
result := format(fmt,[sa[0],sa[1],sa[2],sa[3],sa[4]];

Creat an array in CoDeSys with changeable size

I am working on a moving average algorithm to analyze a sensor values and the values are stored in an Array. BUT, the length of Array is variabla (depends on speed of one motor).
how can I Creat an array in CoDeSys with changeable size.
It's wrong to define Array so :
Name: ARRAY[1...SpeedValue] OF INT ;
I am sorry to tell you that there is no changeable size for arrays in Codesys V2/V3. The general explanation is that there is no Dynamic Memory Allocation available in a PLC because Dynamic Memory Allocation is considered to be too unreliable.
Your only choice is to define an array with a constant ARRAY[1..N_MAX_SPEED_VALUE] and just use the array until SpeedValue
VAR
arrnValues : ARRAY[1..N_MAX_SPEED_VALUE] OF INT;
END_VAR
VAR CONSTANT
N_MAX_SPEED_VALUE : INT := 100; (*Max Array Size*)
END_VAR
For myself I am really bugged by this limitation. I already requested a feature many times, to define arrays like ARRAY[*], have keywords for start and end and define the actual start and end size when instantiating. This has nothing todo with dynamic memory allocation, because size is defined at compile time.
I would recomend you the following post.
https://stefanhenneken.wordpress.com/2016/09/27/iec-61131-3-arrays-with-variable-length/
Stefan describes step by step what is possible to do with variable length arrays.
I wouldn't recommend what Felix sugested because:
First: You never want to have variable scan times.
Second: If for some reason, lets just say something broke and the SpeedValue that you want to be the upper bound of your array is impossible to reach, then you either have a deadlock or a bad output without really knowing if something is wrong
Dynamic array is possible with the help of pointers and operators "__NEW", "__DELETE":
VAR
arrnValues : POINTER TO INT;
SpeedValue : UDINT;
END_VAR
SpeedValue := 100;
arrnValues := __NEW(INT, SpeedValue);
__DELETE(arrnValues);
You must also activate dynamic memory allocation in the Application Properties:
Application Build Options

In order to preallocate memory in Matlab, I want to initialize my array of objects. How do I do this?

I have a class of objects known as blocks. Currently, I am creating an array of blocks using a for loop by simply tacking them unto an empty array
blockArray=[];
for ii=1:Size
blockArray=[blockArray block(....)];
end
In order to preallocate memory, how do I initialize an object array of blocks with dummy values?
For instance if instead of using block objects I used numbers, I could easily preallocate by using zeros(1,Size). Is there something similar that I could do?
The matlab documentation describes
To preallocate the object array, assign the last element of the array first. MATLAB® fills the first to penultimate array elements with default DocArrayExample objects.
So, to do this, instead of iterating over from 1:size, it is simpler to do...
blockArray = []
blockArray(size) = block(...)
The language does not really support this, there exists multiple solutions (or workarounds).
Replicating the first instance
When pushing the first element into the array, you can fill the whole array with this element to achieve a preallocation. This might look very bad, but it is actually the fastest possibility known to me.
for ii=1:S
%assumption e is a scalar, otherwise the code is totally screwed
e=block(....)
if ii==1
%to do preallocation, fill it with your first element
blockArray(1:S)=e
else
blockArray(ii)=e
end
end
Use cell arrays
Obvious simple solution, you can put any class into the fields
blockArray=cell(S,1);
for ii=1:S
%assumption e is a scalar, otherwise the code is totally screwed
e=block(....)
blockArray{ii}=e
end
This solution is very simple but slower than the first. You also lose some functionality which is not available for cell arras
Let your class implement array functionality
classdef A
properties
arg1
out
end
methods
function obj = A(varargin)
if nargin==0
%null object constructor
elseif strcmpi(varargin{1},'createarray')
sz=varargin(2:end);
%preallocate
obj(sz{:})=A;
else
%standard constructor
obj.arg1=varargin{1};
obj.out=[1 2 3;];
end
end
end
end
Constructor with no input argument creates an "empty" or "null" object, this is used to preallocate so it should be empty.
Constructor with first parameter makearray creates an array
Otherwise your constructor should be called.
Usage:
%create an empty object
A
%create an array of size 2,3,4
A('createarray',2,3,4)
%use the standard constructor
A(2)
Biggest downside is you have to modify your classes. Never tested this solution, but it should be close to the first in performance.

Resources