[Implemented] REDIM and UBOUND

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

[Implemented] REDIM and UBOUND

Post 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
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Re: REDIM and UBOUND

Post 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...
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Post by fsw »

Well REDIM should ALWAYS preserve the filled values.
Otherwise it doesn't make sense to have it :wink:

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...
dell_jockey
Enthusiast
Enthusiast
Posts: 767
Joined: Sat Jan 24, 2004 6:56 pm

Post by dell_jockey »

Hi Fred,

ReDim Preserve, or whatever else dynamically redimensions arrays whilst preserving its content, is definitely on my wish-list too.
Last edited by dell_jockey on Wed Mar 17, 2004 1:24 pm, edited 1 time in total.
cheers,
dell_jockey
________
http://blog.forex-trading-ideas.com
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

When you start needs to dynamically allocated, aren't you better off with a lnked list?
dell_jockey
Enthusiast
Enthusiast
Posts: 767
Joined: Sat Jan 24, 2004 6:56 pm

Post 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.
cheers,
dell_jockey
________
http://blog.forex-trading-ideas.com
The_Pharao
User
User
Posts: 57
Joined: Sun Jan 04, 2004 2:11 pm

Post 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.
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post 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.
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post 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.]
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post 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.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Yes, these 2 commands are on my TODO list.
The_Pharao
User
User
Posts: 57
Joined: Sun Jan 04, 2004 2:11 pm

Post 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.
dell_jockey
Enthusiast
Enthusiast
Posts: 767
Joined: Sat Jan 24, 2004 6:56 pm

Post 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 !
cheers,
dell_jockey
________
http://blog.forex-trading-ideas.com
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Post by fsw »

Hmm, it's almost a year that I posted that...
Good to know that it made into the todo list :wink:

Franco
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Redim made it in a while back it seems, any word on whether ubound will be added?
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Post Reply