[beendet]ReAllocateMemory-[Windows98SpeicherBug/-Fehler!]:-(

Fragen und Bugreports zur PureBasic 4.0-Beta.
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

[beendet]ReAllocateMemory-[Windows98SpeicherBug/-Fehler!]:-(

Beitrag von Toshy »

[edit]
Aktueller Beitrag der alles nachvollziehbar macht:
Verfasst: 17 Feb 2006 3:33:58
[/edit]

Hallo.

Mit PB4 beta3 teste ich unter Win98 gerade meine code.
Bin gestern durcheinander gekommen mit einem anderem Beitrag, aber irgendwie verstehe ich da einiges nicht. Daher weiß ich immer noch nicht ob ich nach einem Fehler in meinem Programm suchen muß oder irgendwo intern was falsch läuft (Bug).

Das folgende Problem konnte ich noch nicht mit einem Beispielcode nachvollziehen, geschieht bei mir aber nach jedem start.

Ich arbeite sehr viel mit "Memory". Soweit so gut.
Ich erstelle nun etliche "Datenbanksätze" und immer bei der Zeile 172921 kommt ein Fehler (selber Code ohne was zu füllen, bzw. nur leere Datensätze werden erstellt).

Das eigenartige ist, das der Fehler nichts weiter ist, als das Reallcote memoray NULL zurück liefert und meine "schleife" die das auffangen soll (reallociert so lange bis es klappt) gar nicht mehr beendet wird (immer NULL). Es ist aber noch massig Speicher da (gerade mal ein paar MB verbraucht) und auch von der Anzahl der erstellen oder reallocierten Speicher habe ich schon viel mehr gemacht.

Kann man irgenwie rausbekommen WARUM Reallocatememory NULL liefert?

Bin zwar noch dabei den Fehler genau einzugrenzen, kann natürlich noch ein Fehler von mir sein, deshalb schaue ich noch. Wollte ab er schon mal wissen wie ich eine genauere Fehlermeldung erhalten.

Bis gleich.
Toshy
Zuletzt geändert von Toshy am 19.02.2006 16:45, insgesamt 6-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ein Code, der den Fehler erzeugt wäre vielleicht ganz nützlich.

Bist du sicher, dass du [c]ReAllocateMemory()[/c] als ersten Parameter
auch keine ungültige Speicheradresse übergibst?
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

ReAllocateMemory gibt bei deinem Code ja auch nicht Null zurück, sondern du rufst es garnicht auf. Dein Problem ist das du "While" und "Wend" nicht verstehst. Die Schleife muss nämlich nicht ausgeführt werden. Wenn du "While 0:Debug "a":Wend" schreibst dann wird "a" niemals ausgegeben, nicht so wie bei Repeat-Until.
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Hi. doch wird alles korrekt aufgerufen. der Code in dem anderen Beitrag ist nicht der Code den ich in meinem PRogramm nutze, der ist etwas länger und anders. Habe den nur für das Beispiel neu erstellt. Für den Beispielcode den ich jetzt nutze habe ich den Fehler ausgebessert. Also ne Repeatschleife und zwei Variablen statt einer (damit nach einem Fehler nicht mit NULL weitergearbeitet wird, sonder mit dem Original).

Bin noch am testen, komme dem Fehler aber nächer.
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Hallo.
Folgende Debugausgabe erhalte ich:
start
32*i=4247488
Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden
i=132734 | z=1 | Size=4247488
Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden
i=132734 | z=2 | Size=4247488
Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden
i=132734 | z=3 | Size=4247488
...
erzeugt wird dies durch den Code

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
  Repeat
    *MemoryID = AllocateMemory(Size)
    If *MemoryID = 0
      error(0,"Proc - _AllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
    EndIf
  Until *MemoryID <> 0
  ProcedureReturn *MemoryID
EndProcedure
Global i.l
Procedure.l _ReAllocateMemory(_MemoryID.l, Size.l)
  If _MemoryID = 0
    Debug "das drfte nicht vorkommen; i=" + Str(i) + " | Size=" + Str(Size)
    Delay(5000)
  EndIf
  Protected *MemoryID
  z.l
  Repeat
    *MemoryID = ReAllocateMemory(_MemoryID, Size)
    If *MemoryID = 0
      error(0,"Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
      z +1
      Debug "i=" + Str(i) + " | z=" + Str(z) + " | Size=" + Str(Size)
      Delay(5000)
    EndIf
  Until *MemoryID <> 0
  ProcedureReturn *MemoryID
EndProcedure
; ---------------------------------------- 
; ---------------------------------------- 


;i=132734 | z=1 | Size=4247488

OpenConsole()
Debug "start"
PrintN("start")
*MEM = _AllocateMemory(16)
For i = 1 To 800000
  If i > 132733
    Debug "32*i=" + Str(32*i)
  EndIf
  *MEM = _ReAllocateMemory(*MEM,32*i)
  _AllocateMemory(1)
Next i
PrintN("ende")
Debug "ende"


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

CloseConsole()
Zwar ist die Schleifennummer bei der es auftritt wohl nicht immer gleich, hängt aber mit der größe (hier 32 Byte) des Multiplikatiors zusammen und von anderen Dingen (Systemstart). Bin mir da aber noch n icht so sicher.
Ändere ich nichts, ist es aber immer die selbe Zeile.

Auftreten tut das nur wenn auch das "allocatememory" drinn ist (ich weiß, hier recht sinnlos) und dann wenn 32*i ca. 4 MB groß ist.

Hat mal jemand einen Tip woran das liegen kann?

Gruß
Toshy
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Der Code nochmal erweitert.

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
  Repeat
    *MemoryID = AllocateMemory(Size)
    If *MemoryID = 0
      error(0,"Proc - _AllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
    EndIf
  Until *MemoryID <> 0
  ProcedureReturn *MemoryID
EndProcedure
Global i.l
Procedure.l _ReAllocateMemory(*_MemoryID, Size.l)
  If *_MemoryID = 0
    Debug "das drfte nicht vorkommen; i=" + Str(i) + " | Size=" + Str(Size)
    Delay(5000)
  EndIf
  Protected *MemoryID
  z.l
  Repeat
    *MemoryID = ReAllocateMemory(*_MemoryID, Size)
    If *MemoryID = 0
      error(0,"Proc - _ReAllocateMemory() - Memory konnte nicht zur verfgung gestellt werden")
      z +1
      Debug "i=" + Str(i) + " | z=" + Str(z) + " | Size=" + Str(Size)
      Delay(5000)
    EndIf
  Until *MemoryID <> 0
  ProcedureReturn *MemoryID
EndProcedure
; ---------------------------------------- 
; ---------------------------------------- 


;i=132734 | z=1 | Size=4247488

OpenConsole()

PrintN("start")
*MEM = _AllocateMemory(16)
;StartTime = ElapsedMilliseconds() ;Startzeit - milisekunden fr jeden 
Debug "start"
For i = 1 To 800000
  If ElapsedMilliseconds()-StartTime > 1000
    PrintN("Ausgabe sekndlich,wird extrem langsamer | i="+Str(i))
    StartTime = ElapsedMilliseconds()
  EndIf
  If i > 132733
    Debug "32*i=" + Str(32*i)
  EndIf
  *MEM = _ReAllocateMemory(*MEM,32*i)
  _AllocateMemory(1)
 
Next i
PrintN("ende")
Debug "ende"

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

CloseConsole()
Also der Code ist um einen Timer erweitert, so daß man sehen kann in welchem Schleifenduchlauf man sich gerade befindet. Ausgabe einmal pro Sekunde.
Man sieht auch, das es immer langsamer wird. Hängt wohl mit der Internen verwaltung zusammen. Ist aber doch fast schon recht extrem der Unterschied.
So nun zum wichtigen Teil:

Erstens obwohl ich unter XP nicht richtig testen kann (Rechner IMMER sehr stark ausgelastet) scheint der Geschindigkeitsunterschied hier im Gegensatz zu Win98 nicht so extream unterschiedlich auszufallen.

Zweitens (!!!)
Der Fehler tritt NUR unter Windows98 auf, NICHT unter XP. Da es die selbe EXE ist dürfte das entweder ein Bug sein oder Systembedingt. Da aber eine besonderen Systemfunktionen von mir direkt ausgeführt werden, genug Speicher übrig ist, die "Windows Ressourcen-Anzeige" auch nicht meckert vermute ich das es ein Bug ist. Kann mir den Unterschied zwischen XP und 98 sonst nicht erklären.
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

!!!!!!!!!! ---------- ---------- ---------- !!!!!!!!!!
Hier ist der nachvollziehbare Code
!!!!!!!!!! ---------- ---------- ---------- !!!!!!!!!!

Fehler tritt unter Windows 98 auf.

Hallo. Also ich bin mir jetzt sicher daß es ein Bug ist, nur ob PB oder Windows den verursacht weiß ich nicht.
Wenn ihr den Code testet erhöht sich unter Windows98 ständig der Memorypointer (passiert auch mit Long oder Quad) bis er knapp unter 2 GB liegt. Ruft man dann nochmals ReallocateMemory() auf, so wird warscheinlich versucht eine ID überhalb von 2 GB zu nutzen was natürlich nicht geht (4 GB / 2). Ich dachte nun das unter WindowsXP keine Fehlermeldung kommt, weil XP vielleicht mehr als 2 GB verträgt, aber daran liegt es nicht. Hier wird nicht ständig einfach nur die MemId erhöht sondern der jetzt nicht mehr genutzte niedrigere Bereich genutzt.

Deshalb kam ich ständig durcheinander bei allen anderen Tests. Darauf muß man erstmal kommen.

[edit] Code editiert: "Size.l" in "32*i" geändert, so wir euch der aktuelle Speicherverbrauch bei einem Fehler angezeigt.
Testet doch bitte mal unter Windows98.

Code: Alles auswählen

OpenConsole()
PrintN("start") : Debug "start"
*MEM = AllocateMemory(16)
*MEM2
StartTime.l
For i = 1 To 800000*1000
  If ElapsedMilliseconds()-StartTime > 1000
    PrintN("Ausgabe sekndlich | i="+Str(i) +" | *MEM=" + Str(*MEM ) )
    Debug "*MEM=" + Str(*MEM )
    StartTime = ElapsedMilliseconds()
  EndIf
  *MEM2 = *MEM
  Repeat
    *MEM = ReAllocateMemory(*MEM2, 32*i) ; man kann auch nur "i" nehmen
    If *MEM = 0
      PrintN("_ReAllocateMemory()-Error | i=" + Str(i) + " | Size=" + Str(32*i) + " | *MEM2=" + Str(*MEM2) )
      Debug "_ReAllocateMemory()-Error | i=" + Str(i) + " | Size=" + Str(32*i) + " | *MEM2=" + Str(*MEM2) 
      Delay(5000)
    EndIf
  Until *MEM <> 0
Next i
PrintN("ende") : Debug "ende"
For i = 1 To 600
  Delay(100)
Next i
CloseConsole()
Ach ja, der Fehler tritt auch unter PB 3.94 auf.
Das ist ja richtiger shit, jetzt kann ich nicht eine Zeile Code mehr programmieren, weder unter PB4 und 3.94.
Erst wenn das Problem gehoben ist :-(

[Edit]
debug Windows98(debugger):
start
*MEM=8978444
*MEM=189857804
*MEM=372899852
*MEM=563019788
*MEM=754909196
*MEM=943521804
*MEM=1132724236
*MEM=1322123276
*MEM=1505951756
*MEM=1694564364
*MEM=1887895564
*MEM=2080047116
_ReAllocateMemory()-Error | i=184192 | Size=5902336 | *MEM2=2133131276
debug Windows XP(console):
start
Ausgabe sek³ndlich | i=1 | *MEM=3350160
Ausgabe sek³ndlich | i=34560 | *MEM=6422560
Ausgabe sek³ndlich | i=43904 | *MEM=6750240
Ausgabe sek³ndlich | i=52736 | *MEM=5308448
Ausgabe sek³ndlich | i=58112 | *MEM=7208992
Ausgabe sek³ndlich | i=64128 | *MEM=7405600
Ausgabe sek³ndlich | i=68224 | *MEM=7536672
Ausgabe sek³ndlich | i=72832 | *MEM=7667744
Ausgabe sek³ndlich | i=77056 | *MEM=5308448
Ausgabe sek³ndlich | i=80640 | *MEM=5308448
Ausgabe sek³ndlich | i=84096 | *MEM=10747936
Ausgabe sek³ndlich | i=87808 | *MEM=8126496
Ausgabe sek³ndlich | i=92288 | *MEM=11272224
Ausgabe sek³ndlich | i=96896 | *MEM=8454176
Ausgabe sek³ndlich | i=100608 | *MEM=5308448
Ausgabe sek³ndlich | i=103936 | *MEM=8650784
Ausgabe sek³ndlich | i=107520 | *MEM=8781856
Ausgabe sek³ndlich | i=109824 | *MEM=5308448
.....
....



Gruß
Toshy
Zuletzt geändert von Toshy am 17.02.2006 17:25, insgesamt 3-mal geändert.
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Ich kanns nich nachvollziehen, bei mir dauert es Ewigkeiten biss da halbwegs große Werte für *Mem rauskommen (das größte was ich gesehen hab war 500MB, was danach aber wieder auf 100MB runtergefallen ist) Und dabei war ich schon bei einer MemSize von über 300 MB... Wofür brauchst du so viel Memory?
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
Sylvia
verheiratet<br>1. PureGolf-Gewinner
Beiträge: 487
Registriert: 29.08.2004 09:42
Wohnort: Old Europe

Beitrag von Sylvia »

Habe deinen Code nicht getestet. Was mir aber beim überfliegen
sofort ins Auge stach:

For i=1 to 800000*1000 ; bedeutet =800MB !

und weiter unten dann:

ReAllocateMemory(...,32*i) ; bedeutet 32*800MB = 25,6GB !

25GB ist vielleicht in 4-5 Jahren Standard-Ausstattung; musst halt warten
bis dahin. Dann funktioniert dein Code. :)
Basic Pur = PureBasic
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Hi.
Es wäre nett zu sagen ob ihr unter XP oder 98 testet, denn nur bei 98 tritt der fehler auf. Genau so wichtig ist, ob die MemId ständig steigt (also die Debugausgabe).

Ich benötige zwar sehr wohl später große Mengen speicher, aber darum geht es nicht. Die schleife hätte auch ne "forever" schleife sein können und war nur ein überbleibsel aus meinem Code mit dem man durch das i leicht zählen kann.
Die schleife ist nur so hoch angesetzt um unter XP zu testen und damit sie nicht so schnell aufhört.

Unter Windows98 aber tritt der Fehler bei ca. i = 184192 auf mit einer Größe von 5894144 Bytes, also 5 MB (!!!) nichts mit GigaByte oder so.

Also Sylvia, die Anzahl der Möglichen Schleifendurchläufe hat damit nichts zu tun, geht auch wenn du das"*1000" wegläßt oder bei noch weniger.
Deem2031, hast du denn unter Windows98 getestet wie ich mehrfach geschrieben hatte und wenn ja wie sieht deine Debugausgabe aus (wenn es denn klappt).
Ach ja, Deem2031, es ist eine Datenbank und da ist das nicht ungewöhnlich mal nen GB zu haben. Und besonders wenn es ein Datenbankserver ist.

Kann mir mal jemand den Text von Fred übersezten, dazu reicht es bei mir nicht
The problem here is you ask a big continous chunk of memory, which isn't sure to be reserved. Win98 is also known as being quite weak when dealing with a lot of memory..
[edit]
Der selbe Fehler tritt auf mit AllocateMemory:

Code: Alles auswählen

OpenConsole()
PrintN("start") : Debug "start"
*MEM = AllocateMemory(16)
*MEM2
StartTime.l
For i = 1 To 800000*1000
  If ElapsedMilliseconds()-StartTime > 1000
    PrintN("1/Sek.| i="+Str(i)+" | MemorySize="+Str(32*i)+"/=" +Str((32*i)/(1024*1024))+"MB | *MEM=" + Str(*MEM ) )
    Debug "*MEM=" + Str(*MEM )
    StartTime = ElapsedMilliseconds()
  EndIf
  *MEM2 = *MEM
  FreeMemory(*MEM2) ; test for allocatememory
  errorcounter = 0
  Repeat
    ;*MEM = ReAllocateMemory(*MEM2, 32*i) ; man kann auch nur "i" nehmen
    *MEM = AllocateMemory(32*i) ; test for allocatememory
    If *MEM = 0
      PrintN("_ReAllocateMemory()-Error | i=" + Str(i) + " | Size=" + Str(32*i) + " | *MEM2=" + Str(*MEM2) )
      Debug "_ReAllocateMemory()-Error | i=" + Str(i) + " | Size=" + Str(32*i) + " | *MEM2=" + Str(*MEM2) 
      Delay(5000)
    EndIf
  Until *MEM <> 0
Next i
PrintN("ende") : Debug "ende"
For i = 1 To 600
  Delay(100)
Next i
CloseConsole()
1. Win10
PB6.1
Gesperrt