Seite 1 von 1

Struktur variabel erweitern ?

Verfasst: 29.08.2007 00:00
von Bisonte
Hallo miteinander...

Code: Alles auswählen

Structure lagerdaten

Item.s
Lager.s

Endstructure

...

Item(1)\Item=GetDatabaseString(0)
Item(1)\Lager=GetDatabaseString(1)
wenn nun Lager.s noch eins dazukommt... wie sag ich meinem Programm, das er das auch einlesen soll....

Ein Lager.s[MaxLager] funktioniert leider nicht, Fehlermeldung ....

Wäre es eine LinkList, hätte ich das gleiche Problem mit dem einlesen aus der DB...

Das Table sieht so aus :

Item,Lager1,Lager2,Lager3....usw.

Ein Datensatz demnach

Kuchen,0,2,1,....usw


P.S.: PB 3.3 nicht vergessen ;)

Help ...

Verfasst: 29.08.2007 00:12
von Kaeru Gaman
das geht nur, wenn du von vornherein eine feste anzahl möglicher weiterer lagerorte vorsiehst,
also z.b.

Code: Alles auswählen

Structure lagerdaten
  Item.s
  Lager1.s
  Lager2.s
  Lager3.s
Endstructure
um die größe musst du dir keine sorgen machen, da die strukturierten elemente selber nur 4byte pro pointer brauchen.
an stringspeicher wird nur benötigt was auch belegt wird.

Re: Struktur variabel erweitern ?

Verfasst: 29.08.2007 00:23
von NicTheQuick
Bisonte hat geschrieben:Ein Lager.s[MaxLager] funktioniert leider nicht, Fehlermeldung ....
Wenn du statt MaxLager eine Konstante benutzt, also #MaxLager, dann
funktioniert es. Statische Arrays funktionieren nur mit Konstanten.

Code: Alles auswählen

#MaxLager = 10
Structure lagerdaten
  item.s
  Lager.s[#MaxLager]
EndStructure

Lager.lagerdaten
Lager\item = "Kuchen"
For a = 0 To #MaxLager - 1
  Lager\Lager[a] = Str(Random(1000))
Next

Debug Lager\item
For a = 0 To #MaxLager - 1
  Debug Lager\Lager[a]
Next

Verfasst: 29.08.2007 00:26
von Bisonte
Also in der Datenbank wird bei einer Lagererweiterung ein Table hinzugefügt.

Also sollte ich demnach sagen wir

Code: Alles auswählen

Lager.s[100]
schreiben,dann wird auch nur der Platz im Speicher belegt, wo auch wirklich daten drin sind ? (ok plus 4 Byte für den Pointer also 100*4)

hab ich das so richtig im blick ?

Weil es wohl keine 100 Lager geben wird...Soll also heissen

Code: Alles auswählen

Structure lagerdaten
Item.s
Lager.s[100]
EndStructure

....

Item(1)\Item=GetDataBaseString(0)
For x=1 To AnzahlLager
Item(1)\Lager[x]=GetDataBaseString(x)
Next x
....

War das so gemeint ?

Verfasst: 29.08.2007 00:29
von Bisonte
Das mit der Konstanten hätte den Haken:

Ich muss vorher die Anzahl der Tables ermitteln, und wenn ich

#MaxLager = Lager.l

Schreibe, dann gibts Fehlermeldung...

Verfasst: 29.08.2007 00:30
von NicTheQuick
Ich hab hier auch noch eine andere Möglichkeit, wenn du die willst. Die
müsste auch mit PB V3.3 funktionieren. Hab sie gerade extra etwas
abgeändert. Sie ist auch dynamisch, aber weniger komfortabel.

Code: Alles auswählen

Procedure SetString(*pPtr.Long, String.s)
  Protected Size.l = Len(String)
  
  If Size = 0
    If *pPtr\l
      FreeMemory(*pPtr\l)
      *pPtr\l = 0
      ProcedureReturn #True
    Else
      ProcedureReturn #True
    EndIf
  EndIf
  
  *pPtr\l = ReAllocateMemory(*pPtr\l, Size + SizeOf(Long) + 1)
  
  If *pPtr\l
    PokeL(*pPtr\l, Size)
    PokeS(*pPtr\l + SizeOf(Long), String)
    ProcedureReturn #True
  EndIf
  
  ProcedureReturn #False
EndProcedure

Procedure.s GetString(*pPtr.Long)
  If *pPtr\l
    ProcedureReturn PeekS(*pPtr\l + SizeOf(Long), PeekL(*pPtr\l))
  EndIf
  
  ProcedureReturn ""
EndProcedure

Procedure.l StringLength(*pPtr.Long)
  If *pPtr\l
    ProcedureReturn PeekL(*pPtr\l)
  EndIf
  
  ProcedureReturn 0
EndProcedure

Structure SArray
  *arr
  c.l
EndStructure

Procedure SA_Add(*SArray.SArray, String.s) ;Fügt einen neuen String ans Ende hinzu
  Protected *tmp
  
  *tmp = ReAllocateMemory(*SArray\arr, (*SArray\c + 1) * SizeOf(*tmp))
  If *tmp
    *SArray\arr = *tmp
    *tmp + *SArray\c * SizeOf(*tmp)
    SetString(*tmp, String)
    *SArray\c + 1
    
    ProcedureReturn #True
  EndIf
  
  ProcedureReturn #False
EndProcedure

Procedure SA_Del(*SArray.SArray, pos.l) ;Löscht String an Position
  Protected *tmp
  
  If pos >= 0 And pos < *SArray\c
    *tmp = *SArray\arr + pos * SizeOf(*tmp)
    SetString(*tmp, "")
    MoveMemory(*tmp + SizeOf(*tmp), *tmp, (*SArray\c - pos - 1) * SizeOf(*tmp))
    *SArray\c - 1
    If *SArray\c
      *SArray\arr = ReAllocateMemory(*SArray\arr, *SArray\c * SizeOf(*tmp))
    Else
      FreeMemory(*SArray\arr)
      *SArray\arr = 0
    EndIf
    ProcedureReturn #True
  EndIf
  
  ProcedureReturn #False
EndProcedure

Procedure SA_Set(*SArray.SArray, pos.l, String.s) ;Setzt String
  Protected *tmp
  
  If pos >= 0 And pos < *SArray\c
    *tmp = *SArray\arr + pos * SizeOf(*tmp)
    
    SetString(*tmp, String)
    
    ProcedureReturn #True
  EndIf
  
  ProcedureReturn #False
EndProcedure

Procedure.s SA_Get(*SArray.SArray, pos.l) ;Gibt String zurück
  Protected *tmp
  
  If pos >= 0 And pos < *SArray\c
    *tmp = *SArray\arr + pos * SizeOf(*tmp)
    
    ProcedureReturn GetString(*tmp)
  EndIf
  
  ProcedureReturn ""
EndProcedure

Procedure SA_Move(*SArray.SArray, pos.l, newpos.l) ;Verschiebt String an neue Position
  Protected *String, *tmp.SArray
  
  If pos = newpos : ProcedureReturn #False : EndIf
  If pos >= 0 And newpos >= 0 And pos < *SArray\c And newpos < *SArray\c
    *tmp = *SArray\arr + pos * SizeOf(Long)
    *String = *tmp\arr
    
    If pos < newpos
      MoveMemory(*tmp + SizeOf(*String), *tmp, (newpos - pos) * SizeOf(*String))
      *tmp = *SArray\arr + newpos * SizeOf(*String)
      *tmp\arr = *String
    Else
      *tmp = *SArray\arr + newpos * SizeOf(*String)
      MoveMemory(*tmp, *tmp + SizeOf(*String), (pos - newpos) * SizeOf(*String))
      
      *tmp\arr = *String
    EndIf
  EndIf
EndProcedure

Procedure SA_Clear(*SArray.SArray) ;Löscht das gesamte Array
  Protected a.l, *tmp = *SArray\arr
  
  For a = 1 To *SArray\c
    SetString(*tmp, "")
    *tmp + SizeOf(String)
  Next
  
  If *SArray\arr : FreeMemory(*SArray\arr) : EndIf
  *SArray\arr = 0
  *SArray\c = 0
EndProcedure

Structure Lager
  item.s
  Lager.SArray
EndStructure

Define Lager.Lager

Lager\item = "Kuchen"
items = Random(10)
For a = 1 To items
  SA_Add(Lager\Lager, Str(a))
Next

Debug Lager\item
For a = 1 To Lager\Lager\c  ;Anzahl Elemente
  Debug SA_Get(Lager\Lager, a - 1)
Next

Debug ""
SA_Clear(Lager\Lager)
Debug Lager\Lager\c

Verfasst: 29.08.2007 00:33
von Bisonte
Hossa die Waldfee....

Ich bin doch DER "Pointernoob..." ;)

Da muss ich erstmal sichten was das alles ist ....

Dank ... hier bekommt man ja verdammt schnell ne Antwort ;)

Verfasst: 29.08.2007 08:35
von Kaeru Gaman
> dann wird auch nur der Platz im Speicher belegt, wo auch wirklich daten drin sind ? (ok plus 4 Byte für den Pointer also 100*4)

eigentlich schon. ich würd sicherheitshalber auf der 3.30 noch mal nen testlauf machen.

z.b. sowas:
taskmanager aufmachen, prozessfenster anzeigen, und das hier starten

Code: Alles auswählen

Structure Test
  Item.s
  Name.s[100]
EndStructure
Dim TestLager.Test(999)

Debug "Array ist leer. Speicherbedarf checken."
Delay(10000)  ; 10 sec Pause
Debug "---"
Debug "Array wird nun schrittweise gefüllt."

For n=0 To 99
  Debug "--- Schritt "+Str(n+1)+" ---"
  For t=0 To 9
    For x=0 To 99
      TestLager(10*n+t)\Name[x] = Space(1023)
    Next x
    Debug "Item Nr."+Str(t)+": +100KB"
  Next t
  Debug "Schritt "+Str(n+1)+" abgeschlossen: 1MB beansprucht."
  Delay(1000)
Next n
damit wird in 1-sec-Schritten jeweils 1MB mehr beansprucht.
...auf der 4.02 sieht es sogar so aus, als ob auch der Speicher für die Pointer erst beim belegen wirklich angefordert wird.

Verfasst: 30.08.2007 18:16
von Bisonte
jupp.... bei 3.3 ist es so ;) man kann zusehen wie der Speicher sich vollmüllt ;) Mercy ...