Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

String in dynamischem udt führt zu absturz

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Domso



Anmeldungsdatum: 02.02.2011
Beiträge: 109

BeitragVerfasst am: 04.02.2014, 20:57    Titel: String in dynamischem udt führt zu absturz Antworten mit Zitat

Hallo zusammen

ich habe mich heute ein wenig mit dyn. Speicherreservierung beschäftigt und wollte mal testen, wie man dynamisch in einem udt einen array eines anderen udt erstellen kann.

Prinzipiell hat auch alles funktioniert, zumindest mit integer und double werten. Beim initialisieren einer String variable stürtzt dann mein Programm ab.

Hat jmd da irgendeine Idee, woran das liegen könnte? Ich vermute mal, dass FB intern beim Speicherreservieren für die String-Variable Probleme hat. (?)
Code:

Randomize Timer

'-------------------------Types definieren----------------------------
Type test_type
   As Integer var1
   As Integer Ptr pt_var1
   As double var2
   As String var3
End Type

Type globalType
   As Integer testCount
   As test_type Ptr test
   Declare Sub createtest
   Declare Destructor
End Type
'---------------------------------------------------------------------

Sub globalType.createtest 'erstelle ein neues Objekt
   If this.test=0 Then
      this.testCount=1
      this.test=(Allocate(SizeOf(test_type)))       
   Else
      this.testCount+=1
      this.test=(reAllocate(this.test,this.testCount*SizeOf(test_type)))
   EndIf
   
   'Integer, Double und pointer funktionieren wunderbar
   this.test[this.testCount-1].var1=this.testCount-1
   this.test[this.testCount-1].var2=Rnd
   this.test[this.testCount-1].pt_var1=@this.test[this.testCount-1].var1
   
   'Bei Strings stürtzt das Programm ab
      
   'this.test[this.testCount-1].var3=" "

End Sub

Destructor globalType
   'Speicher wieder freigeben
   DeAllocate this.test
End Destructor


Dim As globalType global
'-------------------------Ausgabe----------------------------
For i As Integer = 0 To 100
   global.createtest
   Print Str(i)&":    @"& @global.test[i] & "  |  "&global.test[i].var1 & "  |  " & global.test[i].var2 & "  |  " & global.test[i].pt_var1
Next

Sleep

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Elor



Anmeldungsdatum: 12.07.2013
Beiträge: 205
Wohnort: Konstanz

BeitragVerfasst am: 04.02.2014, 22:10    Titel: Antworten mit Zitat

Hallo,
bei UDT's muessen Strings immer mit fester laenge angegeben werden, bei dir also z.B:
Code:

Type test_type
   As Integer var1
   As Integer Ptr pt_var1
   As double var2
   As String* 255 var3
End Type


dann muesste es laufen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 04.02.2014, 22:13    Titel: Antworten mit Zitat

In der deutschen Referenz steht ein Hinweis bei Allocate und im englischen Wiki steht dazu auch etwas.

Es ist eigentlich relativ einfach, STRING ist kein nativer Datentyp, sondern eine Art internes UDT mit drei Feldern. Den Aufbau habe ich in einem kleinen Beispiel vor einiger Zeit hochgeladen.

Der String enthält also die Länge des Strings, die Größe des tatsächlich reservierten Speichers (FB reserviert sprungweise, um Zeit zu sparen) und einen Pointer auf den Anfang der Daten.
Wenn du nun für einen String oder ein UDT mit einem String darin mit Allocate Speicher reservierst, hast du an diesen Stellen überall irgendwelche Daten stehen. Wenn du nun auf den String zugreifst, denkt der String, er hat Daten hinterlegt und greift irgendwo hin. Das führt dann zu den Abstürzen. Gleiches Problem wirst du mit ReAllocate haben. Nur CAllocate reserviert Speicher und nullt deren Inhalt.
Alternativ kannst du auch New verwenden.


Dein Code hat aber auch ein weiteres Problem. Das ReAllocate ist nicht gerade performant. Man würde hier eher eine Linked List einsetzen, die nicht ständig Daten hin und herschieben muss. So in der Art funktionieren die Collections in den mdTypes.

Echte dynamische Arrays in UDTs kann man sich auch anders hinbiegen, wenn auch nicht immer schön. Ein Beispiel dazu von mir zeigt das auf und hat auch einen Link auf eine weitere Möglichkeit.
Seit einiger Zeit lassen sich auch echte statische Variablen in UDTs platzieren. Diese können auch Arrays sein, da sie faktisch außerhalb des UDTs existieren. Eine Diskussion dazu gibt es im englischen Forum.

Es wäre auch möglich, dass es bald in FB echte dynamische Arrays in UDTs gibt...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Domso



Anmeldungsdatum: 02.02.2011
Beiträge: 109

BeitragVerfasst am: 05.02.2014, 22:22    Titel: Antworten mit Zitat

hmm ja eigentlich logisch... neutral

performance ist eben anwendungsabhängig.
danke für die hilfe
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz