Author Topic: Wie funktioniert REDIM?  (Read 2118 times)

Offline kanonet

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1137
    • View Profile
    • My GLBasic code archiv
Wie funktioniert REDIM?
« on: 2011-Nov-06 »
Ja, wie funktioniert REDIM eigentlich intern? Ich weiß, wie es einzusetzen ist, aber ich möchte gern wissen, wie es intern arbeitet, damit ich geschwindigkeitsabhängige Vorgänge noch besser optimieren kann.

Wenn ich schreibe:
Code: (glbasic) [Select]
LOCAL a%[], b%[]

DIM a[100]
REDIM a[0]

REDIM b[100]
Würde dann b[] den nicht freigegebenen Speicher von a[] nutzen, oder könnte das ausschließlich a[] selbst? Und falls b[] dazu in der Lage wäre, wie sieht es aus, wenn a[] und b[] sich in verschiedenen Types, Functionen, Subs,... befinden?
Ich weiß nicht, ob dies außer Gernot jemand beantworten kann, auf jeden Fall bedanke ich mich für eure Hilfe.

Grüße.

EDIT: weil ich gerade dabei bin:
Es wäre sehr nützlich, wenn man FOREACH um ein optionales STEP -1 oder ähnliches erweitern könnte, damit man ein Array rückwärts durchsuchen kann, ohne auf die Geschwindigkeit von FOREACH verzichten zu müssen.

EDIT2: wieso gibt das folgende keinen Fehler/Programmcrash?:
Code: (glbasic) [Select]
DIM a[1]
WHILE a[-1]=0
DIMDEL a[], -1
WEND
« Last Edit: 2011-Nov-07 by kanonet »
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10814
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Wie funktioniert REDIM?
« Reply #1 on: 2011-Nov-09 »
1. REDIM macht erstmal ein DIM, dannach werden alte Elemente in das neue Array wieder reinkopiert, bevor das neue Array gelöscht wird. Wenn der Speicherbereich (intern) groß genug ist, dann wird kein Speicher angefordert, sondern nur "neue" Werte mit 0 belegt.

Der Vorteil von REDIM ist, dass die Werte erhalten bleiben.
Ein weiterer Vorteil ist, dass REDIM a[0] intern keinen Speicher freigibt, und somit schnell wieder ein großes Feld erstellen kann. (Auch mit DIM).

FOREACH rückwärts bingt keinen Geschwindikeitszuwachs zu:
Code: (glbasic) [Select]
FOR i% = 0 TO LEN(a[])-1 STEP 5
   ALIAS pa = a[i]
   ...
NEXT

WHILE a[-1] = 0
    DIMDEL a[], -1 // letzes raus, Array ist leer

...
WHILE a[-1] = 0 // crash!!! a[] ist leer. Zugriff auf a[LEN(a[])-1]

Offline kanonet

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1137
    • View Profile
    • My GLBasic code archiv
Re: Wie funktioniert REDIM?
« Reply #2 on: 2011-Nov-09 »
Hallo Kitty, ich danke dir für deine Antworten. ;)

1. REDIM macht erstmal ein DIM, dannach werden alte Elemente in das neue Array wieder reinkopiert, bevor das neue Array gelöscht wird. Wenn der Speicherbereich (intern) groß genug ist, dann wird kein Speicher angefordert, sondern nur "neue" Werte mit 0 belegt.

Der Vorteil von REDIM ist, dass die Werte erhalten bleiben.
Soweit ist mir das klar, trotzdem danke für die Wiederholung.

Ein weiterer Vorteil ist, dass REDIM a[0] intern keinen Speicher freigibt, und somit schnell wieder ein großes Feld erstellen kann. (Auch mit DIM).
Jetzt sind wir am Kern meiner Frage, noch mal präzisiert: Wen REDIM a[0] internen Speicher zur Verfügung stellt, kann dieser dann nur von a[] wieder genutzt werden, oder von jedem beliebigen anderen Array (bspw. b[])? Und wie sieht es mit Arrays aus, die sich in verschiedenen Types, Functions, Subs befinden, können auch diese auf gemeinsam freigegebenen Speicher zugreifen?
Oder kurz zusammengefasst: stellt ein REDIM Speicher global (programmweit) zur Verfügung, oder in irgend einer Form lokal beschränkt?
Sorry, falls ich hier etwas schwer von Begriff sein sollte. :S

FOREACH rückwärts bingt keinen Geschwindikeitszuwachs zu:
Code: (glbasic) [Select]
FOR i% = 0 TO LEN(a[])-1 STEP 5
   ALIAS pa = a[i]
   ...
NEXT
Oh, na gut, dann mache ich es so, bzw. mit der While-Schleife. Danke.

WHILE a[-1] = 0
    DIMDEL a[], -1 // letzes raus, Array ist leer

...
WHILE a[-1] = 0 // crash!!! a[] ist leer. Zugriff auf a[LEN(a[])-1]
Ja, soweit habe ich mir das auch gedacht, dann habe ich es ausprobiert und es gab keinen Crash! Daher ja meine Frage, warum funktioniert dies, statt wie erwartet zu crashen? Codebeispiel 1. Post.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10814
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Wie funktioniert REDIM?
« Reply #3 on: 2011-Nov-10 »
a[-1] bei leerem Feld ist ein Bug -> das greift ausserhalb des Arrays zu.
Der Speicher hängt an dem Variablenobjekt. Also, REDIM a[0] hat keinen Einfluss auf b[].