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:

Frage zu input

 
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: 21.06.2014, 17:59    Titel: Frage zu input Antworten mit Zitat

Hallo,

ich habe gerade gerade ein paar probleme mit input;
also nicht mit dem befehl an sich, sondern mit einer Art nebeneffekt

Beim herumprobieren mit Vererbung und Strings (s. http://forum.qbasic.at/viewtopic.php?p=105124#105124 ), hatte ich des öffteren abstürze und komischerweise war der "input" befehl meistens dran schuld o0
zumindest glaube ich das.

Code:

type myudt extends object
   a as integer=1
   b as Integer=2
End Type


Dim As myudt Ptr tudt =New myudt
Dim As myudt Ptr tudt2=New myudt

dim tstring as string

tstring = space(sizeof(myudt))
for x as integer = 0 to sizeof(myudt) - 1
    tstring[x] = cast(UByte Ptr,Cast(Any Ptr,tudt))[x]
next

Print "|"+tstring+"|"
Sleep

soweit funktikoniert auch alles; doch wenn ich nun am ende nach dem sleep
Code:

Dim As String text
Input text

eigentlich sollte das doch überhaupt nichts ändern, aber wenn man die ausgabe mit und ohne input vergleicht sieht man, dass der anfang (also ich vermute mal der teil von "extends object") verschieden ist?

wie kann das sein? das objekt wird ja eigentlich nur durch input verändert?

neutral
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 21.06.2014, 19:53    Titel: Antworten mit Zitat

Kann das Problem vielleicht an der Konsole liegen? Ich kann den von dir beschriebenen Effekt nicht beobachten, allein schon weil mir sowohl vor als auch nach dem INPUT nichts zwischen den senkrechten Strichen angezeigt wird (also "||").

Ich habe es anders probiert:
Code:
for i as integer = 0 to len(tstring)-1
  print hex(tstring[i]);
next

und da ändert sich bei mir in der Anzeige nichts.

Ich schätze, dass die Ausgabe der Sonderzeichen bei dir irgendwas Unanständiges mit der Konsole anstellt.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Domso



Anmeldungsdatum: 02.02.2011
Beiträge: 109

BeitragVerfasst am: 21.06.2014, 20:40    Titel: Antworten mit Zitat

welche fb version benutzt du?

ich habe jetzt mal das problem bisschen spezifiziert und in 2 programme gepackt

das erste programm speichert den string in eine datei ab und das zweite baut aus diesem wieder den UDT zusammen.

das zweite programm stürzt sofort ab, wenn es versucht eine methode der oberklasse aufzurufen

ohne input am ende funktioniert es problemlos


Code:

Type rootUDT extends object
   As Integer var1=5
   Declare Sub foo
   Declare virtual function foo2 As String
End Type

Sub rootUDT.foo
   Print foo2
End Sub

function rootUDT.foo2 As String
   Return "test"
End Function


type myudt extends rootUDT
   a as Integer=1
   b as Integer=2
   Declare virtual Function foo2 As String
End Type

function myudt.foo2 As String
   Return "test"&a
End Function

Dim As myudt Ptr tudt =New myudt


dim tstring as string

tstring = space(sizeof(myudt))
for x as integer = 0 to sizeof(myudt) - 1
    tstring[x] = cast(UByte Ptr,Cast(Any Ptr,tudt))[x]
Next

Dim As Integer f = freefile
Open "tmp" For Binary As #f
   Put #f,,tstring
Close #f

Sleep


und

Code:


Type rootUDT extends object
   As Integer var1=5
   Declare Sub foo
   Declare virtual function foo2 As String
End Type

Sub rootUDT.foo
   Print foo2
End Sub

function rootUDT.foo2 As String
   Return "test"
End Function

type myudt extends rootUDT
   a as Integer=1
   b as Integer=2
   Declare virtual Function foo2 As String
End Type

function myudt.foo2 As String
   Return "test"&a
End Function

Dim As myudt Ptr tudt =New myudt

dim tstring as string

tstring = space(sizeof(myudt))
Dim As Integer f = freefile
Open "tmp" For Binary As #f
   get #f,,tstring
Close #f

For x as integer = 0 to sizeof(myudt) - 1
   cast(UByte Ptr, Cast(Any Ptr,tudt))[x] =  tstring[x]
next

Print tudt->a 'funktioniert ohne probleme
tudt->foo     'funktioniert nur ohne input

Sleep
Dim As String text
Input text


edit: ich vermute dass am anfang des Strings die vererbungsinfos stehen und diese verändert werdenm wodurch er die dann irgendwie überschreibt
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 22.06.2014, 00:29    Titel: Antworten mit Zitat

Wenn ich aus dem letzten Quellcode das INPUT rausnehme, stürzt es mir trotzdem ab:
Code:
Aborting due to runtime error 12 ("segmentation violation" signal) in test.bas::FOO()

fbc 0.90.1, Linux Debian.

Könnte sein, dass ein unerlaubter Speicherzugriff stattfindet, der bei dir erst einmal unbemerkt bleibt und erst beim INPUT zur Geltung kommt. Ich kenne mich nur leider bei den Pointer-Geschichten nicht wirklich gut aus.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Muttonhead



Anmeldungsdatum: 26.08.2008
Beiträge: 565
Wohnort: Jüterbog

BeitragVerfasst am: 22.06.2014, 08:04    Titel: Antworten mit Zitat

ich vermute mal das die Adressen der Methoden ja erst zur Laufzeit im UDT verdrahtet werden.
Wenn du im 2.Programm den kompletten Inhalt eines UDTs überschreibst, "restaurierst" du die Adressen die fürs erste
Programm zur Laufzeit gültig waren, im grade laufenden 2.Programm aber ins Nirwana zeigen.

Mutton
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Domso



Anmeldungsdatum: 02.02.2011
Beiträge: 109

BeitragVerfasst am: 22.06.2014, 11:58    Titel: Antworten mit Zitat

Zitat:
ich vermute mal das die Adressen der Methoden ja erst zur Laufzeit im UDT verdrahtet werden.
Wenn du im 2.Programm den kompletten Inhalt eines UDTs überschreibst, "restaurierst" du die Adressen die fürs erste
Programm zur Laufzeit gültig waren, im grade laufenden 2.Programm aber ins Nirwana zeige


hmm eigentlich dürfte das aber nicht passieren, weil sizeof funktionen nicht berücksichtigt und sollten damit ja auch nicht im String auftauchen (werden ja auch nicht direkt im ram abgespeichert)

@nemored
wer achtet schon auf compiler meldungen durchgeknallt keine ahnung, aber input wird ja eigentlich nie ausgeführt, das programm stürzt ja schon vorher ab o0
anscheinend darf man die ersten 2 byte tatsächlich nicht anfassen...

Das Problem selber lässt sich vermutlich mit
Code:
For x as integer = 2 to sizeof(myudt) - 1
   cast(UByte Ptr, Cast(Any Ptr,tudt))[x] =  tstring[x]
next

lösen, aber das ändert nichts daran, warum er das überhaupt macht;

ich denke mal da müsste man die genaue implementierung in fbc kennen, um den fehler zu finden weinen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 22.06.2014, 12:59    Titel: Antworten mit Zitat

Ich habe mal versucht, das Ganze ein bisschen aufzudröseln. Also: Der Datentyp "myudt" hat eine Länge von 12 Bytes, wobei die oberen 8 Bytes die Variablen a und b enthalten.

Die unteren 4 Bytes enthalten (hier auf meinem Rechner) einen Wert von 4263972 ohne "Input", einen Wert von 4276264 mit "Input" und nachfolgender Textvariable und einen Wert von 4292648 mit "Input" und nachfolgender Integervariable.

Ohne "Extends Object" in der Typendeklaration ist "myudt" 8 Bytes lang und enthält nur die Variablen a und b.

Das legt die Vermutung nahe, daß es sich bei den unteren 4 Bytes um einen Pointer oder ein Objekthandle handelt.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 22.06.2014, 14:08    Titel: Antworten mit Zitat

Der Größenunterschied ergibt sich, wie schon richtig erkannt, durch "Extends Object". Dadurch erhält dein UDT einen Pointer auf eine VTable. Wenn du jetzt durch dein UDT iterierst und den Pointer überschreibst, brauchst du dich nachher nicht über Abstürze wundern.

Der Object Pointer hängt immer am Anfang, das kannst du dir im folgenden Beispiel ansehen:
Code:
'#Define USE_EXTENDS

#IfDef USE_EXTENDS
   #Define EXTEND_TYPE Extends Object
#Else
   #Define EXTEND_TYPE
#EndIf

Type myudt EXTEND_TYPE
   a As Long = 1
   b As Long = 2
End Type

Dim As myudt tudt

Print *Cast(Long Ptr, Cast(Long Ptr, Cast(Any Ptr, @tudt)) + 0)
Print *Cast(Long Ptr, Cast(Long Ptr, Cast(Any Ptr, @tudt)) + 1)
#IfDef USE_EXTENDS
Print *Cast(Long Ptr, Cast(Long Ptr, Cast(Any Ptr, @tudt)) + 2)
#EndIf

Sleep


Du müsstest also bei der "Extends Object"-Variante die ersten SizeOf(Any Ptr)-Bytes überspringen, dann sollte es gehen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Domso



Anmeldungsdatum: 02.02.2011
Beiträge: 109

BeitragVerfasst am: 22.06.2014, 16:04    Titel: Antworten mit Zitat

danke für die schnelle hilfe happy

welche rolle der befehl input dabei gespielt hat, ist mir trotzdem noch schleierhaft (ich vermute, dass der compiler irgendetwas miteinbindet und sich dadurch das ändert) aber das ist ja nicht so wichtig
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 22.06.2014, 16:07    Titel: Antworten mit Zitat

Domso hat Folgendes geschrieben:
danke für die schnelle hilfe happy

welche rolle der befehl input dabei gespielt hat, ist mir trotzdem noch schleierhaft (ich vermute, dass der compiler irgendetwas miteinbindet und sich dadurch das ändert) aber das ist ja nicht so wichtig


Grundsätzlich gibt es überhaupt keine Garantie wo der vptr hinzeigt, d.h. der Wert kann bei jeder Ausführung woanders hinzeigen (vor allem bei aktiviertem ASLR, was FB aber vmtl nicht kann), oder zumindest bei jeder Neukompilierung des Programms.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 23.06.2014, 07:54    Titel: Antworten mit Zitat

Eins verstehe ich nicht: Wieso ist das doppelte casten bei
Code:
tstring[x] = cast(UByte Ptr,Cast(Any Ptr,tudt))[x]
notwendig? Warum kann tudt nicht direkt zu UByte Ptr gecastet werden?

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 23.06.2014, 08:19    Titel: Antworten mit Zitat

Das liegt daran, dass der Compiler zur Compilezeit prüft, ob der Cast innerhalb der Vererbungsstruktur stattfindet und wenn nicht, einen Fehler wirft. Deswegen muss zunächst nach Any Ptr gecastet werden.

Warum das gut/schlecht ist, kannst du mit dkl im IRC Channel #fb-portal auf Freenode besprechen. zwinkern
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 23.06.2014, 09:20    Titel: Antworten mit Zitat

Zitat:
Warum das gut/schlecht ist, kannst du mit dkl im IRC Channel #fb-portal auf Freenode besprechen.
Nee, lass mal... grinsen

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 23.06.2014, 13:11    Titel: Antworten mit Zitat

In Kurzform: Zwischen Typen zu casten, die "unrelated" sind, ist böse, böse, böse, und erfordert deswegen einen Umweg über einen Typ, der keinen bestimmten Typ repräsentiert. In C++ wäre das z.B. der unterschied zwischen static_cast (selbes Verhalten) und reinterpret_cast bzw C-Style casts, wo man (fast) munter casten kann, wiem an will.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 24.06.2014, 11:47    Titel: Antworten mit Zitat

Diese Einschränkung macht doch eigentlich nur Sinn, wenn dem Compiler zum Zeitpunkt der Kompilierung die Spezifikationen des Objektes, von dem geerbt werden soll, nicht bekannt sind (oder zumindest nicht bekannt sein könnten), oder sehe ich das falsch?

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 24.06.2014, 17:57    Titel: Antworten mit Zitat

grindstone hat Folgendes geschrieben:
Diese Einschränkung macht doch eigentlich nur Sinn, wenn dem Compiler zum Zeitpunkt der Kompilierung die Spezifikationen des Objektes, von dem geerbt werden soll, nicht bekannt sind (oder zumindest nicht bekannt sein könnten), oder sehe ich das falsch?

Welche Einschränkung? Dass ein UByte und ein eigene Klasse nix miteinander zu tun haben, sieht der Compiler, ja. Deswegen klappt der Cast ja nicht.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1279
Wohnort: Ruhrpott

BeitragVerfasst am: 26.06.2014, 17:58    Titel: Antworten mit Zitat

Ich meine die Einschränkung, daß ich einen Pointer nicht ohne Umweg von einem (Pointer-) Typ in einen anderen casten kann. Der Unterschied zwischen den verschiedenen Pointertypen besteht ja nur in der Anzahl der Bytes, die er repräsentiert (wg. Schrittweite beim Indizieren).

Entschuldigung, wenn ich hier vielleicht ein bisschen begriffsstutzig erscheine, aber für mich mit meiner Assembler-Denke hat objektorientierte Programmierung zur Zeit noch viel mystisches (Aber ich arbeite daran und gelobe Besserung zwinkern ).

Mich würde in dem Zusammenhang interessieren, ob der Compiler zum Zeitpunkt der Kompilierung das "extendete" Objekt und dessen genaue Spezifikationen (und damit auch die darin enthaltenen Pointertypern) kennt oder nicht. Oder liege ich jetzt mit dem ganzen Gedankengang daneben?

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail 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