Page 1 of 3
[Implemented] REDIM and UBOUND
Posted: Thu May 15, 2003 6:41 pm
by fsw
I know working on the core language is not that fun as - let's say... on the 3D stuff.
But I would love to see these commands build in the core language...
Thanks
Franco
Re: REDIM and UBOUND
Posted: Thu May 15, 2003 8:01 pm
by tinman
fsw wrote:I know working on the core language is not that fun as - let's say... on the 3D stuff.
But I would love to see these commands build in the core language...
I guess you mean "ReDim Preserve" because you can already re-dimension an array by simply using Dim again ;)
Yes, would be nice...
Posted: Thu May 15, 2003 10:35 pm
by fsw
Well REDIM should ALWAYS preserve the filled values.
Otherwise it doesn't make sense to have it
From the XBasic and XBlite manual:
The DIM Statement dimensions an array and zeros its contents.
When an array is dimensioned, the existing contents are first freed, then memory space for the array is allocated and filled with zeros.
The REDIM Statement redimensions an array and maintains its contents.
When an array is redimensioned, the existing contents not in the new size are lost, the existing contents in both the old and new size are unchanged, and contents in the new size only are zeroed.
Franco
-
In the hope that one fine day PureBasic will have a complete core language...
Posted: Wed Mar 17, 2004 10:21 am
by dell_jockey
Hi Fred,
ReDim Preserve, or whatever else dynamically redimensions arrays whilst preserving its content, is definitely on my wish-list too.
Posted: Wed Mar 17, 2004 11:06 am
by GedB
When you start needs to dynamically allocated, aren't you better off with a lnked list?
Posted: Wed Mar 17, 2004 2:16 pm
by dell_jockey
GedB,
you're right, I could indeed do that...
In my app I need to handle multiple lists that each contain a couple of thousand small records (open-high-low-close-volume of stock quotes). These records are sorted by date/time; sorting order never changes, so we're basically talking about a semi-static sequential list of records here.
For this type of data, I think it would be a hell of an overhead to use linked lists, though. The only reason I'd like to have a 'ReDim Preserve' is to dynamically alter the amount of historical data I pull from the database, for instance when I want to change a 200-days view into a, say, 500-days view. This would merely constitute an enlargement of arrays that exist already and contain data.
Posted: Wed Mar 17, 2004 2:45 pm
by The_Pharao
you can copy the data of your array into a byte buffer. then DIM the array to the new size and copy the old data back into the array.
i have a code for this, will post it when i'm at home.
Posted: Wed Mar 17, 2004 2:50 pm
by GedB
What you need to do then is create a new, enlarged array and copy the old array into it.
This is what the compiler would do anyway.
It will take you a couple of lines, sure, but it prevents people from falling into the usual mistake of constantly resizing arrays and then complaining about performance.
Posted: Wed Mar 17, 2004 4:17 pm
by GedB
By copying blocks of Memory you can easily implement your own Redim.
Code: Select all
Dim a(5)
Procedure ListA(count)
For i = 0 To count
PrintN("A(" + Str(i) + ") = $" + Hex(a(i)))
Next i
Input()
EndProcedure
Procedure RedimA(OldCount, NewCount)
SizeOfA = (OldCount + 1) * 4
BufferAddress = AllocateMemory(0, SizeOfA)
CopyMemory(@a(), BufferAddress, SizeOfA)
Dim a(NewCount)
CopyMemory(BufferAddress, @a(), SizeOfA)
EndProcedure
OpenConsole()
a(0) = $A
a(1) = $B
a(5) = $C
ListA(5)
RedimA(5, 10)
a(7) = $D
a(10) = $E
ListA(10)
CloseConsole()
[edit: just noticed The_Pharao's post. Saved you the trouble

]
[ps: I wonder if the need for an intermediate buffer could be avoided with a bit of inline ASM.]
Posted: Wed Mar 17, 2004 4:27 pm
by GedB
Hmmm,
This version of RedimA works
Code: Select all
Procedure RedimA(OldCount, NewCount)
SizeOfA = (OldCount + 1) * 4
OldAddressOfA = @a()
Dim a(NewCount)
CopyMemory(OldAddressOfA, @a(), SizeOfA)
EndProcedure
But this depends on the call to _HeapFree@12 in PB_FreeArray not filling the memory with 0s. It's also possible for the array to be corrupted. The call to PB_FreeArray really should be after the copy.
Perhaps a preserved Redim would be a good idea, since avoiding the copy to the buffer would be much quicker for very big arrays.
Posted: Wed Mar 17, 2004 5:32 pm
by Fred
Yes, these 2 commands are on my TODO list.
Posted: Wed Mar 17, 2004 6:25 pm
by The_Pharao
this is the code you need:
Code: Select all
;*** Die Funktion "RedimPreserveSave" speichert den Inhalt eines Arrays ***
;*** in den Puffer RedimPuffer ***
Dim RedimPuffer.b(0)
RedimPufferSize.l = 1
Procedure RedimPreserveSave(PtrToArray.l, LengthOfArray.l)
Shared RedimPufferSize.l
Dim RedimPuffer.b(0)
Dim RedimPuffer.b(LengthOfArray)
CopyMemory(PtrToArray, @RedimPuffer(), LengthOfArray)
RedimPufferSize = LengthOfArray
EndProcedure
;*** Die Funktion "RedimPreserveRestore" speichert den Inhalt des Puffer***
;*** in das Array zurück und berücksichtigt dabei die Länge ***
Procedure RedimPreserveRestore(PtrToArray.l, LengthOfArray.l)
Shared RedimPufferSize.l
If LengthOfArray > RedimPufferSize
CopyMemory(@RedimPuffer(), PtrToArray, RedimPufferSize)
Else
CopyMemory(@RedimPuffer(), PtrToArray, LengthOfArray)
EndIf
Dim RedimPuffer.b(0)
EndProcedure
this is an example:
Code: Select all
; add a new strct to our array!
;first, save current array
RedimPreserveSave (@Player(0), SizeOf(strctPlayer) * (PlayerUbound+1))
;Array set new size
PlayerUbound = PlayerUbound + 1
Dim Player.strctPlayer(0) ;don't know if you need this line anyway
Dim Player.strctPlayer(PlayerUbound)
;copy old information into resized array
RedimPreserveRestore(@Player(0), SizeOf(strctPlayer) * (PlayerUbound))
this works with any array, you just need to hand over the pointer to the first member of any array (member zero) and the length of the array (size of the structure * total count of array members [PlayerUbound+1 in my example]).
hope this helps you out
edit:
note: i don't know if you really need the "Dim RedimPuffer.b(0)" like calls.
Posted: Thu Mar 18, 2004 9:50 am
by dell_jockey
GedB, Pharao:
Thanks for your support & code snippets. I'll test your ideas/implementations the coming days.
Fred:
Good to hear that ReDim will one day be supported natively !
Posted: Sun Mar 21, 2004 4:06 am
by fsw
Hmm, it's almost a year that I posted that...
Good to know that it made into the todo list
Franco
Posted: Mon Apr 14, 2008 1:55 am
by pdwyer
Redim made it in a while back it seems, any word on whether ubound will be added?