Seite 1 von 1

[beendet] Proceduren-reallocatememory->Blödheit [WinFehle

Verfasst: 16.02.2006 08:08
von Toshy
Hallo Leute,
also das war ne Nacht, seit ca. 15 Stunden bin ich ununterbrochen mit dem folgenden Problem am Rechner beschäftigt. Die Nacht ist durchgemacht und nun bin ich k.o.

Ich wunderte mich und wunderte mich denn mein Code habe ich zwar in den letzen Programmierwochen noch nie getestet, aber von der theorie müßte alles richtig sein. beim erstmaligen Start klappte aber nichts. Ja ja, jetzt denken alle "ist doch klar, man kann doch nicht wochen lang programmieren und dann klappt es gleich", aber bei mir meißt schon. Mache das oft so das ich erst nur aus dem Kopf ohne testen alles mache.
Na ja, also bin ich rann an das prüfen, aber mein Köpfle sagt mir es müßte alles richtig sein. Also rann ans testen. Nichts klappte, also die ganze Nacht mit dem "Ausschlußverfahren" verbracht und eigenartiger Weise habe ich den Fehler in einem Code gefunden der bisher immer ging.

Ich rufe AllocateMemory und ReAllocateMemory nie direkt auf, sondern eine eigene Procedure, die dafür sorgt, das der Speicher immer korrekt erstellt wird (na ja, keine NULL zurückgegeben wird).
Bitte sagt jetzt nicht, das ich keine Pointer verwenden soll, geht ja ums Prinzipt nicht ob es schon ist oder nicht.

Also Schaut euch mal die Ergebnisse des gleich folgenden Codes an.
Alle drei Aufrufe (Procedure 1 und 2 und der direkte Aufruf) Liefern unterschiedliche Ergebnisse. Eine Procedure gibt totale Fehlergebnisse aus, die zweite nur in der ersten Zeile.
Das stimmt doch was nicht !!?

Problem tritt unter Win 98/XP auf. PB4 beta2.

Code: Alles auswählen

Procedure error(w.l,s.s)
  If ErrorConsole = 0 
    ErrorConsole = OpenConsole()
  EndIf
  ;PrintN("error("+Str(w)+"): " )
  ;PrintN( s)
  Debug s
EndProcedure
Procedure.l _AllocateMemory(Size.l)
  Protected *MemoryID
  While *MemoryID = 0
    *MemoryID = AllocateMemory(Size)
    If *MemoryID = 0
      error(0,"Proc - _AllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
    EndIf
  Wend
  ProcedureReturn *MemoryID
EndProcedure

Procedure.l _ReAllocateMemory(*MemoryID, Size.l)
  While *MemoryID = 0
    *MemoryID = ReAllocateMemory(*MemoryID, Size)
    If *MemoryID = 0
      error(0,"Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
    EndIf
  Wend
  Debug "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(*MemoryID)) + " | *MemoryID=" + Str(*MemoryID)
  PrintN( "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(*MemoryID)) + " | *MemoryID=" + Str(*MemoryID) )
  ProcedureReturn MemoryID
EndProcedure

Procedure.l x_ReAllocateMemory(MemoryID.l, Size.l)
  While MemoryID = 0
    MemoryID = ReAllocateMemory(MemoryID, Size)
    If MemoryID = 0
      error(0,"Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
    EndIf
  Wend
  Debug "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(MemoryID)) + " | *MemoryID=" + Str(MemoryID)
   PrintN( "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(MemoryID)) + " | *MemoryID=" + Str(MemoryID) )
  ProcedureReturn *MemoryID
EndProcedure
; ---------------------------------------- 
; ---------------------------------------- 


OpenConsole()

*MEM = AllocateMemory(16)
Debug "meine alte originale Procedure mit Pointer:"
PrintN("meine alte originale Procedure mit Pointer:")
For i = 1 To 5
  *MEM = _ReAllocateMemory(*MEM,16+(i*16))
Next i
*MEM = AllocateMemory(16)
Debug "meine neue Procedure mit Long:"
PrintN("meine neue Procedure mit Long:")
For i = 1 To 5
  *MEM = x_ReAllocateMemory(*MEM,16+(i*16))
Next i

*MEM = AllocateMemory(16)
Debug "direkt mit Pointer:"
PrintN("direkt mit Pointer:")
For i = 1 To 5
  *MEM = ReAllocateMemory(*MEM,16+(i*16))
  Debug "16+(i*16)=" +Str(16+(i*16)) + " | MemorySize()=" + Str(MemorySize(*MEM)) + " | *MemoryID=" + Str(*MEM)
  PrintN( "16+(i*16)=" +Str(16+(i*16)) + " | MemorySize()=" + Str(MemorySize(*MEM)) + " | *MemoryID=" + Str(*MEM) )
Next i


For i = 1 To 600
  Delay(100)
Next i

CloseConsole()
Kann mir mal jemand erklären wie das kommt? Ob ich da was falsch verstehe oder so!?
Ich selber vermute ja ein oder zwei Bugs, anders kann ich mir das nicht erklären

[edit]
Seit wann ist eigendlich die Beta3 draußen? Habe das noch gar nicht bemerkt. Werde die aber jetzt erstmal nicht mehr testen. Meine Augen brennen zu dolle.
Nachtrag: Habe gerade gesehen, daß es gestern Abend raus kam.
[edit2]
Es hatte sich beim erstellen einen nachvollziehbaren Codes ein Tippfehler eingeschlichen. Als Ergebniss der Richtigstellung laufen nun beide Proceduren nicht, aber warum?

Gruß
Toshy

Re: (Bug?) Proceduren - reallocatememory - Bug oder Blödheit

Verfasst: 16.02.2006 08:22
von Deeem2031
Ich setzte 5 Euro auf die Antwort "Blödheit" :mrgreen:

->

Wozu ist denn die "While *MemoryID = 0"-Schleife gut? Ohne die funktioniert das prima:

Code: Alles auswählen

Procedure.l _ReAllocateMemory(*MemoryID, Size.l)
  ;While *MemoryID = 0
    *MemoryID = ReAllocateMemory(*MemoryID, Size)
    If *MemoryID = 0
      error(0,"Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
    EndIf
  ;Wend
  Debug "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(*MemoryID)) + " | *MemoryID=" + Str(*MemoryID)
  PrintN( "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(*MemoryID)) + " | *MemoryID=" + Str(*MemoryID) )
  ProcedureReturn *MemoryID
EndProcedure
Mit der Schleife kann der Buffer ja nur einmal allociert werden, sprich die MemSize bleibt immer bei 16 (Ist ja der Anfangswert)

Und bei "x_ReAllocateMemory(MemoryID.l, Size.l)" steht am Ende "ProcedureReturn *MemoryID", was warscheinlich "ProcedureReturn MemoryID" heißen sollte.

Verfasst: 16.02.2006 08:43
von Toshy
[edit]
habe gerade quatsch geschrieben, bin wohl zu müde. text kommt später.
[edit2]

So, hat sich erstmal erledigt.
Das beispiel ist oben Quatsch, ebenso die Erklärung. Den Code oben verwende ich so gar nicht, habe ihn natürlich gekürzt (auch die proceduren), dabei aber nicht kopiert sondern neu getippt und dabei Fehler gemacht. Habe bei mir ne Repeatschleife und keine While und mein testen war jetzt erst mal sinnlos. Hehe, so ist das, wenn man zu müde ist macht man viele dumme Fehler. und wenn mann blöde ist noch mehr ;-)

So, ich mache jetzt wirklich erstmal pause sonst bekomme ich gar nichts mehr hin.
Code im Kopfe erstellen kann ich zwar Wochen im vorraus, aber man Code kopieren ist wohl zu schwer. *grins*

Also ohne Ausrede:
Da war ich mal zu blöde.

Danke erstmal.

Gruß
Toshy

Verfasst: 16.02.2006 08:52
von Deeem2031
Nagut, dann setzt ich halt 1 Mio Euro auf "Blödheit".
Selbst wenn das jetzt wirklich so wäre würde ich es nicht bereuen :twisted:

Überleg doch mal, "While *MemoryID = 0" startet die Schleife nur wenn *MemoryID = 0 ist. Sprich wenn der Speicher nicht allociert wurde.
Da aber nach dem ersten allocieren *MemoryID <> 0 ist, kann die Schleife nie mehr ausgeführt werden - der Speicher wird also nicht reallocatet.
In deiner letzten Schleife rufst du "*MEM = ReAllocateMemory(*MEM,16+(i*16))" direkt auf, ohne "While *Mem = 0", desswgen funktioniert das auch.

Wenn du aber unbedingt da eine Schleife haben willst, machs so:

Code: Alles auswählen

Procedure.l _ReAllocateMemory(*MemoryID, Size.l) 
  Repeat
    *MemoryID = ReAllocateMemory(*MemoryID, Size) 
    If *MemoryID = 0 
      error(0,"Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden") 
    EndIf 
  Until *MemoryID <> 0 
  Debug "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(*MemoryID)) + " | *MemoryID=" + Str(*MemoryID) 
  PrintN( "Size=" +Str(Size) + " | MemorySize()=" + Str(MemorySize(*MemoryID)) + " | *MemoryID=" + Str(*MemoryID) ) 
  ProcedureReturn MemoryID 
EndProcedure
Auch wenn ich das ganze ohne (Endlos-)Schleife wesentlich sinnvoller finde.

Verfasst: 19.02.2006 16:56
von Toshy
Hallo.
Das Problem besteht weiter, es war kein Fehler an meinem Code wie ich rausgefunden habe, auch kein wirkiches Strukturproblem. Es lag und liegt leider an Windows98.
Zwar werden alle Speicher korrekt freigegeben, aber kurz gesagt der Speicher wird fragmentiert und kann fragmentiert nicht für Speicherbereiche genutzt werden die größer sind als das entsprechnede Fragment. Selbst dann nicht, wenn ALLE Fragmente zusammenhängen.
Sehr eigenartig, aber nicht änderbar.
Man muß also akzeptieren das früher oder später das Programm hängenbleibt und das mit einbeziehen bzw. man kann es wenigstens erträglich rauszögern oder durch Einschränkungen in der Nutzung umgehen, etwas auf jedenfall.

Es wäre aber hilfreicher gewesen nicht einfach an Windows98 zu meckern oder zum tausendsten Mal zu sagen das man dafür nicht mehr programmieren soll, sondern sagen was denn falsch läuft. Und wenn man es nich weiß, das sagen bzw. gar nichts dazu sagen ;-)

ich habe jetzt "unendlich viele" Pointerwerde gesehn und sie kommen mir langsam zum Hals raus ;-)

Danke und Gruß Thorsten