Seite 1 von 2

Krise mit IMA bei AllocateMemory()

Verfasst: 14.02.2008 13:51
von gnasen
Hallo, ich habe mal wieder ein (scheinbar) triviales Problem, was mich sehr beschäftigt:

Code: Alles auswählen

Procedure SendString(ConID.l, text.s, typus.l)
  
  Protected tempTypus.s = Str(typus)
  
  If Len(tempTypus) < 2
    tempTypus = "0" + tempTypus
  EndIf
  
  
  If ConID
    
 
    Protected Outtext.s = ""

    Outtext = "<" + ">" + tempTypus + text + "<\>"
    
    Protected laenge.l = Len(Outtext)
    
    Protected *buffer = AllocateMemory(laenge)
    PokeS(*buffer, Outtext, Len(Outtext))
    SendNetworkData(ConID, *buffer, MemorySize(*buffer))
    
    FreeMemory(*buffer)
    
    Debug "Send: " + Outtext
    
  EndIf 
  
EndProcedure
Hierbei handelt es sich um meine Prozedur zum verschicken von Nachrichten (In Tags etc. zum Buffern beim Empfänger).

Allerdings tritt ab und an ein IMA in dieser Zeile auf

Code: Alles auswählen

Protected *buffer = AllocateMemory(laenge)
Ich hab allerdings keine Ahnung warum? Was könnte der Fehler sein?

Bespiel: SendString(ServerID, "2;4;3;0;|", 13)

ergibt manchmal einen Fehler

Verfasst: 14.02.2008 14:18
von #NULL
bin mir nich sicher, aber probiermal:
(alllocate laenge +1, für den nullchar, und außerdem nur buffer tun wenn buffer gut)

Code: Alles auswählen

    Protected *buffer = AllocateMemory(laenge+1)
    If *buffer
      PokeS(*buffer, Outtext, Len(Outtext))
      SendNetworkData(ConID, *buffer, MemorySize(*buffer))
   
      FreeMemory(*buffer)
   
      Debug "Send: " + Outtext
    EndIf

Re: Krise mit IMA bei AllocateMemory()

Verfasst: 14.02.2008 14:20
von Kiffi
ich weiß zwar nicht, warum der IMA auftritt und in letzter Konsequenz müsste
man untersuchen, warum es so ist, aber ich persönlich würde es unter
Umgehung von AllocateMemory wie folgt machen:

Code: Alles auswählen

Procedure SendString(ConID.l, text.s, typus.l)
  [...]
    Outtext = "<" + ">" + tempTypus + text + "<\>"
    
    SendNetworkData(ConID, @Outtext, Len(Outtext))
  [...]
EndProcedure
Grüße ... Kiffi

Verfasst: 14.02.2008 16:57
von gnasen
Mit dem Nullchar hatte ich auch schon getestet, allerdings änderte dies nichts (hatte schon vieles getestet), aber Kiffi, deine Lösung ist so einfach wie genial (und ich Blind & Doof :( )

Danke :allright:

PS: Aber warum dieser IMA... Es ergibt irgendwie keinen Sinn...

Verfasst: 14.02.2008 17:06
von HeX0R
gnasen hat geschrieben: PS: Aber warum dieser IMA... Es ergibt irgendwie keinen Sinn...
Der IMA hat auch nix mit dem Codeausschnitt zutun, der braut sich ganz woanders in deinem Code zusammen.

Verfasst: 14.02.2008 17:42
von NicTheQuick
Ich hätte noch eine verkürzte Version anzubieten, die auch mit Unicode
funktioniert.

Code: Alles auswählen

Procedure SendString(ConID.l, text.s, typus.l)
  
  If ConID
    Protected Outtext.s = "<>" + RSet(Str(typus), 2, "0") + text + "<\>"
    Protected laenge.l = Len(Outtext)
    
    SendNetworkData(ConID, @Outtext, laenge * SizeOf(Character))
    
    Debug "Send: " + Outtext
  EndIf
EndProcedure

Verfasst: 14.02.2008 17:43
von gnasen
na Prima, der Debugger sagt Zeile 77 in der und der Codedatei und das passt nicht?

Trotzdem, mit Kiffis Variante läufts, also musses da liegen....

Und noch so als Info, keine Threads oder so, die da reinpfuschen könnten!

Verfasst: 14.02.2008 17:51
von HeX0R
Warum eigentlich kein SendNetworkString() ?
Das sollte sogar von Haus aus mit Unicode klar kommen.

Ausserdem ist das was #Null da oben geschrieben hat auch nicht zu vernachlässigen.
Weiss ja nicht, wie oft du deine Prozedur bereits aufgerufen hattest, bevor der Fehler kam, weil du nunmal jedesmal über den allokierten Bereich geschrieben hattest (durch das Nullbyte) was dann eben irgendwann zu einem IMA kommt/kommen kann.

Verfasst: 14.02.2008 18:09
von gnasen
Ich dachte, der Aufruf von FreeMemory() würd genau das tun:
Aufräumen.

Dann sollte eine neue allokierung doch kein Problem sein, oder nicht?

Verfasst: 14.02.2008 18:40
von HeX0R
Nein, darum gehts nicht:
Jedesmal, wenn du einen String mit deiner o.g. Prozedur gesendet hast, hast du über den jeweils neu allokierten Bereich geschrieben.
Das kann 100 mal gutgehn, beim 101. mal erwischst du einen Bereich, der woanders benötigt wird, dann krachts halt irgendwann später (in deinem Fall eben beim erneuten allokieren, das kann aber auch ganz woanders sein).