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
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 ...