Recent

Author Topic: how to empty an dynamic array  (Read 11434 times)

frederic

  • Full Member
  • ***
  • Posts: 226
how to empty an dynamic array
« on: December 07, 2017, 05:07:27 pm »
dear specialists

may be stupid question

i have a dynamic array  with length x
this array is temporary completely filled during calculations and is not needed anymore

during the  same session   i want to use  the same calculation with array length y  ;

uptill now i had always the situation where y> x  and i could use the already present array elements

now i have  y<x  and do not need the former array elements anymore.  I want them to be nil until i fill them again

what is the best way

frederic

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: how to empty an dynamic array
« Reply #1 on: December 07, 2017, 05:12:04 pm »
Code: Pascal  [Select][+][-]
  1. procedure FreeAndNilArray( var aArray:Array of Something);
  2.   Procedure FreeNil(aIndex:Integer); inline;
  3.   var
  4.      vItem:TObject;
  5.   begin
  6.      vItem := aArray[aIndex];
  7.      aArray[aIndex] := nil;
  8.      vItem.Free;
  9.   end;
  10. var
  11.   vCntr:Integer;
  12. begin
  13.   For vCntr:= 0 to Length(aArray) do
  14.     Freenil(vCntr);
  15. end;
  16.  
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: how to empty an dynamic array
« Reply #2 on: December 07, 2017, 05:57:45 pm »
I would do that in reverse order... using downto
Code: Pascal  [Select][+][-]
  1. var
  2.   vCntr:Integer;
  3. begin
  4.   For vCntr:= x to downto y do
  5.     Freenil(vCntr);
  6. end;
« Last Edit: December 07, 2017, 06:02:33 pm by Thaddy »
Specialize a type, not a var.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: how to empty an dynamic array
« Reply #3 on: December 07, 2017, 06:22:03 pm »
Or you can get the compiler to do the clean-up for you:
Code: Pascal  [Select][+][-]
  1. procedure FreeArrayOfObject(const anObjArray: array of TObject);
  2. var
  3.   obj: TObject;
  4. begin
  5.   for obj in anObjArray do
  6.     obj.Free;
  7.   Finalize(anObjArray);
  8. end;

If frederic's dynamic array of pointers are not instantiated classes but are entities allocated with New(), then of course they should be freed in the procedure with Dispose().

Nitorami

  • Sr. Member
  • ****
  • Posts: 481
Re: how to empty an dynamic array
« Reply #4 on: December 07, 2017, 07:43:07 pm »
All responses imply that the array keeps a list of objects which need to be freed, which might be inferred from the phrase "I want them to be nil". However the question is not really clear on that.

If the array keeps simple values instead, the obvious solution would be
SetLength (aArray,0);
SetLength (aArray,x);

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: how to empty an dynamic array
« Reply #5 on: December 07, 2017, 08:51:06 pm »
Or you can get the compiler to do the clean-up for you:
Code: Pascal  [Select][+][-]
  1. procedure FreeArrayOfObject(const anObjArray: array of TObject);
  2. var
  3.   obj: TObject;
  4. begin
  5.   for obj in anObjArray do
  6.     obj.Free;
  7.   Finalize(anObjArray);
  8. end;

If frederic's dynamic array of pointers are not instantiated classes but are entities allocated with New(), then of course they should be freed in the procedure with Dispose().

The finalize looks a bit strange. First, it is not a dynamic but an open array, and second, there are no elements to finalize, and the array is CONST not var, so changes should not propogate back

frederic

  • Full Member
  • ***
  • Posts: 226
Re: how to empty an dynamic array
« Reply #6 on: December 07, 2017, 09:38:57 pm »
thanks all of you,

my question was indeed general one .
One which you can use in a standarised way by simply use the arrayname and its type

thanks again

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: how to empty an dynamic array
« Reply #7 on: December 07, 2017, 09:44:31 pm »
@marco
Indeed, you are correct on all three observations.

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: how to empty an dynamic array
« Reply #8 on: December 08, 2017, 03:12:25 am »
Definitely always go from
Code: Pascal  [Select][+][-]
  1. Length(SomeArray) - 1 downto 0
or 
Code: Pascal  [Select][+][-]
  1. Count - 1 downto 0
as Thaddy suggested, any time you're dealing with an array or list of non-simple types that need to be freed individually. Other than that, there's not much to it... just call
Code: Pascal  [Select][+][-]
  1. SetLength(TheArray, 0);
or
Code: Pascal  [Select][+][-]
  1. TheList.Free;

Also I saw some people suggested "for-in" loops, but personally I'd say avoid these, as even though they're definitely nicer to read code-wise the performance hit when you have a lot of them getting called over and over again is pretty significant due to all the GetEnumerator while-loop stuff. (A big part of the problem is that enumerators basically have to be implemented as classes unless you want to use TP objects, so you end up constantly creating and freeing new instances of them every time you go through the loop. Would be nice to be able to use advanced records for that instead, although I'm not sure how feasible that is from an FPC development standpoint...)
« Last Edit: December 08, 2017, 07:56:44 am by Akira1364 »

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: how to empty an dynamic array
« Reply #9 on: December 08, 2017, 03:25:11 am »
I would do that in reverse order... using downto
Code: Pascal  [Select][+][-]
  1. var
  2.   vCntr:Integer;
  3. begin
  4.   For vCntr:= x to downto y do
  5.     Freenil(vCntr);
  6. end;
Definitely always go from
Code: Pascal  [Select][+][-]
  1. Count - 1 downto 0
or
Code: Pascal  [Select][+][-]
  1. Length(SomeArray) - 1 downto 0
as Thaddy suggested, if it's an array of non-simple types that need to be freed individually. Other than that, there's not much to it... just call
Code: Pascal  [Select][+][-]
  1. SetLength(TheArray, 0);


It makes no difference in this case. The count stays constant through the process so going up or down does not matter. The  top to bottom approach is a must only when the array length is reduced inside the loop too.

Having said that I admit it does not hurt at all it might even help the loop speed or optimizations.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: how to empty an dynamic array
« Reply #10 on: December 08, 2017, 04:02:38 am »
It makes no difference in this case. The count stays constant through the process so going up or down does not matter. The  top to bottom approach is a must only when the array length is reduced inside the loop too.

Having said that I admit it does not hurt at all it might even help the loop speed or optimizations.

Well yeah, I was just pointing it out as a "good habit to get into" sort of thing.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: how to empty an dynamic array
« Reply #11 on: December 08, 2017, 04:11:26 am »
It makes no difference in this case. The count stays constant through the process so going up or down does not matter. The  top to bottom approach is a must only when the array length is reduced inside the loop too.

Having said that I admit it does not hurt at all it might even help the loop speed or optimizations.

Well yeah, I was just pointing it out as a "good habit to get into" sort of thing.
True. In the mean time there is one point that will create the TS troubles that no one mentioned yet.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: how to empty an dynamic array
« Reply #12 on: December 08, 2017, 07:49:11 am »
Not sure what you mean by "TS troubles"?

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: how to empty an dynamic array
« Reply #13 on: December 08, 2017, 08:32:15 am »
All responses imply that the array keeps a list of objects which need to be freed, which might be inferred from the phrase "I want them to be nil". However the question is not really clear on that.

If the array keeps simple values instead, the obvious solution would be
SetLength (aArray,0);
SetLength (aArray,x);
And if the array is only used in a procedure you have nothing to do, because after the procedure alle variables will be freed.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

 

TinyPortal © 2005-2018