Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 13.10.2013, 16:35 Titel: |
|
|
@ThePuppetMaster: Nein, das geht so nicht. In der Zeile Code: | *Cast(UInteger Ptr, @rueck[y]) = Mks(Cvs(*Cast(UInteger Ptr, @g[y])) * verst) | stecken gleich mehrere Fehler. "Cvs" wandelt einen String in eine Single-Zahl, der Wert, den du aus "g" gelesen hast, ist aber UInteger. Dann wandelst du das Ergebnis der Multiplikation in einen String um, und versuchst, ihn als UInteger-Zahl zurückzuschreiben. Das geht auch sehr viel einfacher mit Code: | *Cast(Single Ptr, @rueck[y]) = *Cast(Single Ptr, @g[y]) * verst | oder wie weiter oben schon beschrieben mit Code: | *Cast(Single Ptr, @g[y]) *= verst | direkt in "g".
@nemored: Ich habe die Function gemäß dem Beispiel von "Addition an Pointern" umgeschrieben Code: | Function ampfloat (g As String) As String
Dim As Integer y
Dim As Single Ptr gp
gp = StrPtr(g)
For y = 0 To Len(g)/SizeOf(Single)-1
*gp *= verst
gp += 1
Next
Return g
End Function | Sie funktoniert wunderbar, ist gegenüber der Version aus meinem letzten post stilistisch sauberer und hat sogar einen leichten Geschwindigkeitsvorteil (73,4 Sekunden gegenüber 74,9 Sekunden für 23 Dateien mit insgesamt 1,39GB). Nur wenn ich versuche, "gp" direkt als Laufvariable zu nehmen Code: | For gp = StrPtr(g) To StrPtr(g) + Len(g)/SizeOf(Single) | bekomme ich einen Type mismatch error - allen Versuchen mit "Cast" und eigenen Pointervariablen zum Trotz.
Zitat: | meinPointer = @meineVariable
so etwas? Wenn ja, dann hatte ich dich falsch verstanden | Ich meinte da eher was in der ArtAber da bekomme ich eine Fehlermeldung. Ist ja auch nicht nötig, ich kann ja eine eigene Pointervariable definieren und damit arbeiten.
Vielen Dank für eure Tips und Denkanstöße.
Gruß
grindstone |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 13.10.2013, 17:12 Titel: |
|
|
*vergugt* .. kann gelöscht werden!
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Zuletzt bearbeitet von ThePuppetMaster am 13.10.2013, 17:24, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 13.10.2013, 17:22 Titel: |
|
|
@ThePuppetMaster: Worauf beziehst du dich jetzt?
Gruß
grindstone |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 13.10.2013, 18:06 Titel: |
|
|
Zitat: | ch meinte da eher was in der Art
) |
Wenn du so was vor hast, dann musst du halt generell mit Pointern arbeiten, die du dann entsprechend umbiegst. Wenn du (ohne Pointereinsatz) eine Variable deklarierst, bekommt sie eine Adresse zugewiesen, die du nicht selbst umdefinieren kannst - immerhin findet da auch eine automatische Speicherreservierung und -freigabe statt, die du sonst gehörig durcheinander bringen würdest.
ThePuppetMaster bezog sich wohl auf sein eigenes Posting, das er wieder editiert hat, weil die Antwort nicht zur Fragestellung gepasst hat - vermute ich zumindet. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 13.10.2013, 19:25 Titel: |
|
|
Ist schon klar. Die selbst definierte Pointervariable macht genau das, was ich wollte: Auf einen genau definierten 4 Byte langen Abscnhnitt eines Strings zuzugreifen und die dort vorgefundenen Daten als "Single"-Wert zu behandeln, und das möglichst schnell.
Wie ich inzwischen herausgefunden habe, kann man den Pointer auch direkt als Laufvariable verwenden. Code: | Function ampfloat (g As String) As String
Dim As Integer y
Dim As Single Ptr gp
For gp = StrPtr(g) To StrPtr(g) + Len(g)
*gp *= verst
Next
Return g
End Function | Die For/Next-Schleife zählt automatisch in Viererschritten weiter. Einfacher geht's nicht mehr.
Gruß
grindstone |
|
Nach oben |
|
|
RockTheSchock
Anmeldungsdatum: 04.04.2007 Beiträge: 138
|
Verfasst am: 13.10.2013, 23:41 Titel: |
|
|
Allerdings muss es man noch 4 byte also die größe eines Singles abziehen, Sonst hat man evt. einen fehlerhaften Speicherzugriff, weil man über das Ende des Strings hinausschreibt!
Code: | For gp = StrPtr(g) To StrPtr(g) + Len(g)-4
|
|
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 13.10.2013, 23:57 Titel: |
|
|
Vermutlich -1 statt -4, weil ja auch das automatisch multipliziert werden sollte - habe ich jetzt aber nicht nachgeprüft. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 13.10.2013, 23:59 Titel: |
|
|
-1 ist richtig @nemored.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
RockTheSchock
Anmeldungsdatum: 04.04.2007 Beiträge: 138
|
Verfasst am: 14.10.2013, 08:19 Titel: |
|
|
Ich bitte euch das nochmal zu überprüfen. Es wird ja nur der gp hochgezählt und zwar statt mit 1 bei Integern mit der Länge vom Inhalt des Pointers.
Es muss -4 also -1*len(single)
sein. Das hilft übrigens auch bei einem String mit einer Länge die kein vielfaches von 4 ist. z.b. SPACE(11). Dann läuft die Schleife korrekterweise 2 mal!
Code: | Dim shared as Single verst = 2
Function ampfloat (g As String) As String
Dim As Single Ptr gp
Print "von ";StrPtr(g);" bis ";StrPtr(g) + Len(g) - 4
For gp = StrPtr(g) To StrPtr(g) + Len(g) - 4
Print gp,*gp,
*gp *= verst
Print *gp
Next
Return g
End Function
Dim as String s
s=SPACE(12) 'größe von 3 singles
s=ampfloat(s)
sleep
|
|
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 14.10.2013, 09:16 Titel: |
|
|
RockTheSchock, nemored und ThePuppetMaster haben Recht, Asche auf mein Haupt.
Ich habe das Ganze mal auf einem Stück Papier symbolisch aufgemalt und anschließend das Programm mit verschiedenen Werten laufen lassen und die Schleifendurchläufe mitgezählt.
Mathematisch korrekt ist -1, es funktioniert aber auch mit Werten zwischen -2 und -4.
Mit ohne etwas abzuziehen gibt es bei einer Stringlänge von 1000000 Zeichen 250001 Schleifendurchläufe, also einen zuviel (Das sind dann die nicht reproduzierbaren Programmabstürze, die alle 3 Wochen einmal auftreten). Bei Werten zwischen -1 und -4 gibt es 250000 Schleifendurchläufe und bei -5 249999, also einen zu wenig.
Korrekt muß es also heißen:
Code: | Function ampfloat (g As String) As String
Dim As Single Ptr gp
For gp = StrPtr(g) To StrPtr(g) + Len(g) - 1
*gp *= verst
Next
Return g
End Function |
Gruß
grindstone |
|
Nach oben |
|
|
RockTheSchock
Anmeldungsdatum: 04.04.2007 Beiträge: 138
|
Verfasst am: 14.10.2013, 09:59 Titel: |
|
|
Achtung! -4 bzw len(SINGLE) ist richtig. -1 funktioniert nur, wenn du garantieren kannst, dass die Länge des Strings ein vielfaches von 4 ist.
Probier doch mal!
SPACE(5), sollte nur nur einen Schleifendurchlauf produzieren! Es wird zwar wahrscheinlich nie Probleme mit -1 geben da Speicher eh mit vielfachen von 4 byte(oder 8 oder 16) reserviert wird aber vom prinzip her kann man nie auschließen, dass der speicher doch byte aligned ist und damit so auf das nullbyte und auf die 2 undefinierten bytes hinter SPACE(5) geschrieben wird. |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 14.10.2013, 10:10 Titel: |
|
|
@RockTheSchock
Code: |
Dim foo_byte as byte ptr
foo_byte = allocate(16)
Print "BYTE"
print "basis-position:"; foo_byte
print "pos-0:"; foo_byte; " "; @foo_byte[0]
foo_byte += 1
print "pos-1:"; foo_byte; " "; @foo_byte[0]
Print
Dim foo_short as short ptr
foo_short = allocate(16)
Print "SHORT"
print "basis-position:"; foo_short
print "pos-0:"; foo_short; " "; @foo_short[0]
foo_short += 1
print "pos-1:"; foo_short; " "; @foo_short[0]
Print
Dim foo_integer as integer ptr
foo_integer = allocate(16)
Print "INTEGER"
print "basis-position:"; foo_integer
print "pos-0:"; foo_integer; " "; @foo_integer[0]
foo_integer += 1
print "pos-1:"; foo_integer; " "; @foo_integer[0]
Print
|
wie du siehst, zählt FB hier correkt. Wenn du mit pointer arbeitest, dann addiert fb hier adressentechnisch die richtige menge auf.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 14.10.2013, 10:17 Titel: |
|
|
@RockTheSchock: Alle Werte funktionieren nur, wenn die Länge des Strings ein vielfaches von 4 ist! Wenn nicht, greift der Pointer entweder über das Ende des Strings hinaus auf Speicherstellen zu, oder am Ende des Strings steht Datenmüll, der nicht berücksichtigt wird. Die korrekte Länge des Strings muß vom aufrufenden Programm sichergestellt werden.
Wie ich weiter oben schon erwähnt habe, sind die übergebenen Daten zwar formell ein String, weil sich andere Datentypen nicht so als Block handhaben lassen, in Wirklichkeit handelt es sich aber um eine Reihe von Audiosamples. Die Länge des Strings ist in diesem Fall also immer ein Vielfaches von 8 (weil stereo).
Gruß
grindstone |
|
Nach oben |
|
|
RockTheSchock
Anmeldungsdatum: 04.04.2007 Beiträge: 138
|
Verfasst am: 14.10.2013, 10:18 Titel: |
|
|
Bitte schau dir mal an was hier passiert! Es werden bei SPACE(5) 2 Scheifendurchläufe erzeugt!
Code: | Dim shared as Single verst = 2
Function ampfloat (g As String) As String
Dim As Single Ptr gp
Print "von ";StrPtr(g);" bis ";StrPtr(g) + Len(g) - 1
For gp = StrPtr(g) To StrPtr(g) + Len(g) - 1
Print gp,*gp,
*gp = &h41414141
Print *gp
Next
Return g
End Function
Dim as String s,s2
s=SPACE(5)
For ps As UByte ptr= StrPtr(s) To StrPtr(s)+Len(s)+3
Print *ps;"|";
Next
Print
s2=ampfloat(s)
For ps As UByte ptr= StrPtr(s) To StrPtr(s)+Len(s)+3
Print *ps;"|";
Next
sleep |
|
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 14.10.2013, 10:38 Titel: |
|
|
Natürlich! Der String hat ja auch eine unerlaubte Länge. Der erste Durchlauf greift auf die ersten 4 Bytes des Strings zu, der zweite Durchlauf auf das 5. Byte und weitere 3 Bytes mit undefiniertem Inhalt.
Wie ThePuppetMaster schon bemerkte: Zitat: | also ... sagen wirs mal so ... mit pointer zu "spielen" kann sehr sehr gefährlich sein. |
Gruß
grindstone |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 16.10.2013, 08:49 Titel: |
|
|
@RockTheSchock .. warum machst du hier +3?
Code: | For ps As UByte ptr= StrPtr(s) To StrPtr(s)+Len(s)+3 |
das ist ja auch unsinnig, bzw. unzulässig. du pointest über 3 stellen des allozierten speichers hinaus.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
RockTheSchock
Anmeldungsdatum: 04.04.2007 Beiträge: 138
|
Verfasst am: 16.10.2013, 13:32 Titel: |
|
|
ThePuppetMaster hat Folgendes geschrieben: | @RockTheSchock .. warum machst du hier +3?
Code: | For ps As UByte ptr= StrPtr(s) To StrPtr(s)+Len(s)+3 |
das ist ja auch unsinnig, bzw. unzulässig. du pointest über 3 stellen des allozierten speichers hinaus. |
Genau ich lese ein bisschen hinter den allozierten Speicher, um zu zeigen, dass der Speicher überschrieben wird. |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 16.10.2013, 13:35 Titel: |
|
|
öm .. "lol" ?!? ... was passiert, wenn man auserhalb eines speicherbereichs schreibt, kann man nicht vorhersagen. Das ist generell eine katastrophe, und sollte man tunlichst unterlassen.
Ich weis nicht genau, was du damit demonstrieren möchtest?.?.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 16.10.2013, 15:21 Titel: |
|
|
Wenn man das obige Verfahren auf einen String anwendet, dessen Länge nicht ein Vielfaches von 4 ist, macht man sowieso von vornherein etwas falsch. Entweder man durchläuft nicht den kompletten Speicherbereich oder man durchläuft zu viel Speicher - so oder so erreicht man nicht das, was man eigentlich haben will. Entweder der String hat eine ohne Rest durch 4 teilbare Länge, oder man muss es sowieso anders machen.
(Meine Meinung ) _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 16.10.2013, 15:37 Titel: |
|
|
notfalls kannst du es auch einfach so lösen:
Code: | for x = start to start + len - (len mod sizeof(pointer)) |
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Zuletzt bearbeitet von ThePuppetMaster am 26.01.2014, 16:47, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
|