Invalid memory access

Anfängerfragen zum Programmieren mit PureBasic.
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Beitrag von freak »

Ein crash bei FreeMemory() ist sogut wie immer ein Heap Problem.
Das hilft: http://www.purebasic.fr/blog/?p=55
Benutzeravatar
GreyEnt
Beiträge: 376
Registriert: 20.07.2006 19:41

Beitrag von GreyEnt »

@Kiffi
jo. Da haste recht. Ich wolte aber erstmal die "Anweisungen" befolgen.
Ich progge PureBasic weil Jägermeister nen dicken Kopf macht.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

@freak

aha, verstehe
Now, if you happen to write over the end of this buffer by just a few bytes, you destroy the heap structure without getting any error.
... ein PokeS() schreibt doch immer auch die end-null, oder?

das bedeutet, es wird mit dem letzten PokeS(z,Chr(10)) eine Null über das erste byte des Heap geschrieben.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Kaeru Gaman hat geschrieben:ich würd tatsächlich zur sicherheit auch noch yk und xk gegen 0 prüfen.
Formel: (xk*2+2)*yk

xk und yk sind sicher immer positiv ... somit spielt der Wert von xk keine
Rolle, da die Klammer immer größer als 2 ist.
Problematisch wärs, wenn xk = -1 ist ... dann ist die Klammer nämlich 0.
Es muss also lediglich yk überprüft werden, damit ein Wert größer als 0
raus kommt.

Ja, PokeS() schreibt immer eine abschließende NULL.
Somit also ein einfacher Denkfehler :D

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
GreyEnt
Beiträge: 376
Registriert: 20.07.2006 19:41

Beitrag von GreyEnt »

@Frosch
wenn Du was zu beanstanden hast dann ist da devinitiv was drann.
Ich werde das nochmal "debugen"

Code: Alles auswählen

bs=feld((b-1)*xk+c) 

bei b machst du -1, aber bei c nicht.... 
das führt dazu, dass du die erste spalte des arrys nicht behandelst.
prinzipell führt meine Berechnung zum richtigen Ergebnis. zumindest hab ich schon einige Maps damit fabriziert.

z.B. Koordinate b=1 ; c=1 xk und Yk sind die Felddimensionen xk=100 yk=100

(1-1)*100+1 ergibt 1
macht also die erste Position im Array von feld.
Ich progge PureBasic weil Jägermeister nen dicken Kopf macht.
Benutzeravatar
GreyEnt
Beiträge: 376
Registriert: 20.07.2006 19:41

Beitrag von GreyEnt »

@PMV

Ja, PokeS() schreibt immer eine abschließende NULL.
Somit also ein einfacher Denkfehler

also ich reserviere ein Byte mehr als ich brauche(schreibe). und nie mehr
probleme?

edit das kenne ich doch. :( das thema kamm doch schonmal. ich schäme mich. :(
Ich progge PureBasic weil Jägermeister nen dicken Kopf macht.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

GreyEnt hat geschrieben:@PMV

Ja, PokeS() schreibt immer eine abschließende NULL.
Somit also ein einfacher Denkfehler

also ich reserviere ein Byte mehr als ich brauche(schreibe). und nie mehr
probleme?

edit das kenne ich doch. :( das thema kamm doch schonmal. ich schäme mich. :(
Nein, du reservierst so viele Byte wie du brauchst ... wenn du in den
speicher einen Nullterminierten String schreiben willst, dann brauchst du
auch entsprechend die (Zeichenlänge+1) * Sizeof(CHARACTER) :wink:
PokeS() schreibt einen String in den Speicher und in PB sind Strings nun
mal Nullterminiert. Wenn ich mir aber deinen Code anschaue brauchst du
das garnicht. Somit solltest du auch nicht PokeS() verwenden. Alternative
ist hier CopyMemory() oder PokeC(). Hm, oder noch besser
CopyMemoryString(), wenn das kein abschließendes Null schreibt, dann
würd dein Programm wesentlich kürzer werden :wink:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ich würde eher dazu neigen, wenn die map schon als string gespeichert werden soll,
sie auch als string zusammenzustellen und als ein string in die datei zu schreiben.
also, statt des mehrfachen PokeS("Nr") einfach Out$ + "Nr"

grundsätzlich würde ich die Map nicht als klarschrift speichern, sondern als binary, so ähnlich wie hier:
http://www.purebasic.fr/german/viewtopic.php?t=2131

bzw. wenn schon klarschrift, dann lieber depictive sonderzeichen,
damit man sie mit nem texteditor effektiv editieren kann...



> z.B. Koordinate b=1 ; c=1 xk und Yk sind die Felddimensionen xk=100 yk=100

das hab ich mir schon gedacht, und du bekommst damit ja auch kein Array Index Out Of Bounds...

aber tatsächlich reservierst du mit Dim Map( 100, 100) ein Array mit 101 x 101 Feldern, mit jeweils den Indices 0-100.

also, du kannst auch mit ( xk-1, yk-1 ) dimensionieren,
und die schleifen von 0 bis xk-1 laufen lassen,
damit ist das 0-99 und exakt 100 elemente.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
GreyEnt
Beiträge: 376
Registriert: 20.07.2006 19:41

Beitrag von GreyEnt »

>ich würde eher dazu neigen, wenn die map schon als string gespeichert >werden soll,
>sie auch als string zusammenzustellen und als ein string in die datei zu >schreiben.
>also, statt des mehrfachen PokeS("Nr") einfach Out$ + "Nr"
Das hatte ich anfangs auch. Hab nen Zeilenweise String erzeugt und abgespeichert. Ist aber bei großen Maps recht lahm.

>grundsätzlich würde ich die Map nicht als klarschrift speichern, sondern >als binary, so ähnlich wie hier:
>http://www.purebasic.fr/german/viewtopic.php?t=2131

>bzw. wenn schon klarschrift, dann lieber depictive sonderzeichen,
>damit man sie mit nem texteditor effektiv editieren kann...
das trifft zu. ich möchte die möglichkeit haben nen Texteditor zu benutzen.
aber was ist falsch wenn in der Datei "00" für Wasser;"01" für Land steht?

>> z.B. Koordinate b=1 ; c=1 xk und Yk sind die Felddimensionen >>xk=100 >yk=100

>das hab ich mir schon gedacht, und du bekommst damit ja auch kein >Array Index Out Of Bounds...

>aber tatsächlich reservierst du mit Dim Map( 100, 100) ein Array mit >101 x 101 Feldern, mit jeweils den Indices 0-100.
oh ja. shit. das meinst du damit.


>also, du kannst auch mit ( xk-1, yk-1 ) dimensionieren,
>und die schleifen von 0 bis xk-1 laufen lassen,
>damit ist das 0-99 und exakt 100 elemente.
das wird fluks korrigiert.
Ich progge PureBasic weil Jägermeister nen dicken Kopf macht.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Das hatte ich anfangs auch. Hab nen Zeilenweise String erzeugt und abgespeichert. Ist aber bei großen Maps recht lahm.

hm... ist vielleicht auch ne Frage der Vorgehensweise.

ich meine, du benötigtest keine zeilenweise strings.
ein einziger großer String, der ebenfalls #CRLF$ enthält wie dein buffer jetzt ginge auch.
dann hast du nicht jede zeile einen schreibzugriff, das könnte schon
einen wesentlichen geschwindigkeitsgewinn ausmachen.

dazu kommt, dass dynamische strings evtl. etwas langsamer sind als Fixstrings.
du könntest deinen Bufferstring auch vor den Schleifen, dort wo jetzt dein Allocate steht, mit
Define Buffer.s{(xk*2+2)*yk}
reservieren, dann spart sich dein programm ne menge hin-und-her-geschiebe bei der poolverwaltung.
(müßtest du prüfen, wie das mit re-definen aussieht, ob PB das anstandslos zuläßt)


> aber was ist falsch wenn in der Datei "00" für Wasser;"01" für Land steht?

"falsch" ist daran garnichts.

aber eine latte zahlen, die ohne pause hintereinanderstehen, das kann man nicht grad augenfreundlich nennen.

es gibt ne menge ASCII-Zeichen, also würde dir auch ein zeichen pro Tile genügen.
und ein "@" für Fels, "." für Gras, "~" für Wasser, "#" für Mauer, etc.
ist nun mal viel beschreibender, die Karte wird beim editieren per textedi auf einmal übersichtlich.
das kann man mit einer zuordnungtabelle wieder in werte von 00 bis 31 übersetzen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten