Alternative für dynamische Arrays in Strukturen?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Der Beschreibung nach ist das ein Fall für XML :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Purebasic mach keine Prüfung auf bereichsüberschreitung von Arrays.
Das must man selber machen. Finde ich aber Gut

Code: Alles auswählen

Structure udtDaten
  lVal.l
  fltVal.f
EndStructure


Structure udtDatenArray
  ds.udtDaten[0]
EndStructure

; Speicher anfordern

*daten.udtDatenArray = AllocateMemory(10000 * SizeOf(udtDaten))

For i = 1 To 10000
  With *daten
    \ds[i]\lVal = i
    \ds[i]\fltVal = i / 100.0
  EndWith
Next

For i = 1 To 10000 Step 100
  With *daten
    Debug \ds[i]\lVal
    Debug \ds[i]\fltVal
  EndWith
Next
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Mit dem Problem hab ich mich auch länger rumgeschlagen und hab mir dann gesagt, ich benötige eine neue Liste. Nach mühseligen Arbeiten hab ich mir eine eigene Liste gebastelt, die auf einem Interface basiert. Wenn du diese haben möchtest, brauchst du mich nur Fragen (ist ein bischen umständlich, da Elemente immer als Pointer vorhanden sein müssen).
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

mk-soft hat geschrieben:

Code: Alles auswählen

Structure udtDaten
  lVal.l
  fltVal.f
EndStructure


Structure udtDatenArray
  ds.udtDaten[0]
EndStructure

; Speicher anfordern

*daten.udtDatenArray = AllocateMemory(10000 * SizeOf(udtDaten))

For i = 1 To 10000
  With *daten
    \ds[i]\lVal = i
    \ds[i]\fltVal = i / 100.0
  EndWith
Next

For i = 1 To 10000 Step 100
  With *daten
    Debug \ds[i]\lVal
    Debug \ds[i]\fltVal
  EndWith
Next
Das ist genau was ich brauche, cool. Muss ich mir nur mein eigenes ReDim programmieren, was halt den Speicher allokiert und wieder freigibt, aber das ist ja kein Problem. Thx. :allright:
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Achtung Bug!!!

War wohl etwas müde.
Bei *daten.udtDatenArray = AllocateMemory(10000 * SizeOf(udtDaten)) ist der Index natürlich 0..9999 und nicht 1 bis 10000


Speicherleck bei Strukturen mit Strings und AllocateMemory

FreeMemory gibt ja nur den Speicher der Struktur wieder frei.
Nicht aber den Speicher der von den Strings verwendet wird.
Dieses muss man vorher selber ausführen.

Code: Alles auswählen

; Strukturen
Structure udtDaten
  lVal.l
  fltVal.f
  strVal.s
EndStructure


Structure udtDatenArray
  ds.udtDaten[0]
EndStructure

; Compiler erwingen '_SYS_FreeString@4' anzulegen
Procedure Dummy()
  Protected Dummy.s
  Dummy = ""
EndProcedure
; String speicher komplett freigeben  
Procedure FreeString(*Adr)
  !PUSH   dword [p.p_Adr]
  !CALL  _SYS_FreeString@4
EndProcedure

; -------------------------------------------------------------------


; Speicher anfordern
*daten.udtDatenArray = AllocateMemory(10000 * SizeOf(udtDaten))
; Daten füllen
For i = 0 To 9999
  With *daten
    \ds[i]\lVal = i
    \ds[i]\fltVal = i / 100.0
    \ds[i]\strVal = "Wert: " + Str(i)
  EndWith
Next
; Daten ausgeben
For i = 0 To 9999 Step 100
  With *daten
    Debug \ds[i]\lVal
    Debug \ds[i]\fltVal
    Debug \ds[i]\strVal
  EndWith
Next
; Speicher freigeben
For i = 0 To 9999
  FreeString(@*daten\ds[i]\strVal)
Next
FreeMemory(*daten)
FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Deinen Dummy kannste weglassen und FreeString ändern :wink:

Code: Alles auswählen

;; String speicher komplett freigeben 
Procedure FreeString(*Adr)
  Protected Dummy.s
  !PUSH   dword [p.p_Adr]
  !CALL  _SYS_FreeString@4
EndProcedure
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

:allright:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Little John

Beitrag von Little John »

2mk-soft:
Dein Code erweitert die vorhandenen Möglichkeiten beträchtlich!
Dann ist evtl. zu hoffen dass sowas bald direkt in PB eingebaut ist? :D
Willst Du den Code nicht bis dahin bei "Code, Tipps und Tricks" einstellen?
Er ist IMHO zu wichtig, als dass er irgendwo in den Tiefen des Forums verbleiben sollte.

Gruß, Little John
Antworten